mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
Merge branch 'LennardSchwarz-add-basic-auth'
This commit is contained in:
@@ -82,7 +82,8 @@ the [past releases changelog](docs/changelog.md).
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
Clone this repo, install the dependencies, and run the development server:
|
Clone this repo, install the dependencies (all locally), and run the development server (which auto-watches the
|
||||||
|
files for changes):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/enricoros/big-agi.git
|
git clone https://github.com/enricoros/big-agi.git
|
||||||
@@ -91,15 +92,21 @@ npm install
|
|||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
The app will be running on `http://localhost:3000`
|
The development app will be running on `http://localhost:3000`. Development builds have the advantage of not requiring
|
||||||
|
a build step, but can be slower than production builds. Also, development builds won't have timeout on edge functions.
|
||||||
|
|
||||||
Integrations:
|
## 🌐 Deploy manually
|
||||||
|
|
||||||
* Local models: Ollama, Oobabooga, LocalAi, etc.
|
The _production_ build of the application is optimized for performance and is performed by the `npm run build` command,
|
||||||
* [ElevenLabs](https://elevenlabs.io/) Voice Synthesis (bring your own voice too) - Settings > Text To Speech
|
after installing the required dependencies.
|
||||||
* [Helicone](https://www.helicone.ai/) LLM Observability Platform - Models > OpenAI > Advanced > API Host: 'oai.hconeai.com'
|
|
||||||
* [Paste.gg](https://paste.gg/) Paste Sharing - Chat Menu > Share via paste.gg
|
```bash
|
||||||
* [Prodia](https://prodia.com/) Image Generation - Settings > Image Generation > Api Key & Model
|
# .. repeat the steps above up to `npm install`, then:
|
||||||
|
npm run build
|
||||||
|
npm run start --port 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
The app will be running on the specified port, e.g. `http://localhost:3000`
|
||||||
|
|
||||||
## 🐳 Deploy with Docker
|
## 🐳 Deploy with Docker
|
||||||
|
|
||||||
@@ -115,7 +122,7 @@ docker run -d -p 3000:3000 big-agi
|
|||||||
Or run the official container:
|
Or run the official container:
|
||||||
|
|
||||||
- manually: `docker run -d -p 3000:3000 ghcr.io/enricoros/big-agi`
|
- manually: `docker run -d -p 3000:3000 ghcr.io/enricoros/big-agi`
|
||||||
- or, with docker-compose: `docker-compose up`
|
- or, with docker-compose: `docker-compose up` or see [the documentation](docs/deploy-docker.md) for a composer file with integrated browsing
|
||||||
|
|
||||||
## ☁️ Deploy on Cloudflare Pages
|
## ☁️ Deploy on Cloudflare Pages
|
||||||
|
|
||||||
@@ -127,7 +134,13 @@ Create your GitHub fork, create a Vercel project over that fork, and deploy it.
|
|||||||
|
|
||||||
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fenricoros%2Fbig-agi&env=OPENAI_API_KEY,OPENAI_API_HOST&envDescription=OpenAI%20KEY%20for%20your%20deployment.%20Set%20HOST%20only%20if%20non-default.)
|
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fenricoros%2Fbig-agi&env=OPENAI_API_KEY,OPENAI_API_HOST&envDescription=OpenAI%20KEY%20for%20your%20deployment.%20Set%20HOST%20only%20if%20non-default.)
|
||||||
|
|
||||||
|
## Integrations:
|
||||||
|
|
||||||
|
* Local models: Ollama, Oobabooga, LocalAi, etc.
|
||||||
|
* [ElevenLabs](https://elevenlabs.io/) Voice Synthesis (bring your own voice too) - Settings > Text To Speech
|
||||||
|
* [Helicone](https://www.helicone.ai/) LLM Observability Platform - Models > OpenAI > Advanced > API Host: 'oai.hconeai.com'
|
||||||
|
* [Paste.gg](https://paste.gg/) Paste Sharing - Chat Menu > Share via paste.gg
|
||||||
|
* [Prodia](https://prodia.com/) Image Generation - Settings > Image Generation > Api Key & Model
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# Authentication
|
||||||
|
|
||||||
|
`big-AGI` does not come with built-in authentication. To secure your deployment, you can implement authentication
|
||||||
|
in one of the following ways:
|
||||||
|
|
||||||
|
1. Rebuild `big-AGI` with support for [HTTP Basic Authentication](#http-authentication)
|
||||||
|
2. Utilize user authentication features provided by your [cloud deployment platform](#cloud-deployments-authentication)
|
||||||
|
3. Develop a custom authentication solution
|
||||||
|
|
||||||
|
## HTTP Authentication
|
||||||
|
|
||||||
|
[HTTP Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) is a simple method
|
||||||
|
to secure your application. To enable it in `big-AGI`, you **must manually build the application**:
|
||||||
|
|
||||||
|
- Build `big-AGI` with HTTP authentication enabled:
|
||||||
|
- Clone the repository
|
||||||
|
- Rename `middleware_BASIC_AUTH.ts` to `middleware_BASIC_AUTH.ts`
|
||||||
|
- Build: follow the build instructions in [Deploy manually](../README.md#-deploy-manually) or [Deploying with Docker](deploy-docker.md)
|
||||||
|
|
||||||
|
- Configure the following [environment variables](environment-variables.md) before launching `big-AGI`:
|
||||||
|
```dotenv
|
||||||
|
HTTP_BASIC_AUTH_USERNAME=<your username>
|
||||||
|
HTTP_BASIC_AUTH_PASSWORD=<your password>
|
||||||
|
```
|
||||||
|
|
||||||
|
- Start the application
|
||||||
|
|
||||||
|
## Cloud Deployments Authentication
|
||||||
|
|
||||||
|
> This approach allows you to enable authentication without rebuilding the application by using the features
|
||||||
|
> provided by your cloud platform to manage user accounts and access.
|
||||||
|
|
||||||
|
Many cloud deployment platforms offer built-in authentication mechanisms. Refer to the platform's documentation
|
||||||
|
for setup instructions:
|
||||||
|
|
||||||
|
1. [CloudFlare Access / Zero Trust](https://www.cloudflare.com/zero-trust/products/access/)
|
||||||
|
2. [Vercel Authentication](https://vercel.com/docs/security/deployment-protection/methods-to-protect-deployments/vercel-authentication)
|
||||||
|
3. [Vercel Password Protection](https://vercel.com/docs/security/deployment-protection/methods-to-protect-deployments/password-protection)
|
||||||
|
4. Let us know when you test more solutions (Heroku, AWS IAM, Google IAP, etc.)
|
||||||
@@ -44,6 +44,10 @@ PUPPETEER_WSS_ENDPOINT=
|
|||||||
|
|
||||||
# Backend Analytics
|
# Backend Analytics
|
||||||
BACKEND_ANALYTICS=
|
BACKEND_ANALYTICS=
|
||||||
|
|
||||||
|
# Backend HTTP Basic Authentication
|
||||||
|
HTTP_BASIC_AUTH_USERNAME=
|
||||||
|
HTTP_BASIC_AUTH_PASSWORD=
|
||||||
```
|
```
|
||||||
|
|
||||||
## Variables Documentation
|
## Variables Documentation
|
||||||
@@ -94,21 +98,23 @@ It is currently supported for:
|
|||||||
|
|
||||||
Enable the app to Talk, Draw, and Google things up.
|
Enable the app to Talk, Draw, and Google things up.
|
||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
|:-------------------------|:------------------------------------------------------------------------------------------------------------------------|
|
|:---------------------------|:------------------------------------------------------------------------------------------------------------------------|
|
||||||
| **Text-To-Speech** | [ElevenLabs](https://elevenlabs.io/) is a high quality speech synthesis service |
|
| **Text-To-Speech** | [ElevenLabs](https://elevenlabs.io/) is a high quality speech synthesis service |
|
||||||
| `ELEVENLABS_API_KEY` | ElevenLabs API Key - used for calls, etc. |
|
| `ELEVENLABS_API_KEY` | ElevenLabs API Key - used for calls, etc. |
|
||||||
| `ELEVENLABS_API_HOST` | Custom host for ElevenLabs |
|
| `ELEVENLABS_API_HOST` | Custom host for ElevenLabs |
|
||||||
| `ELEVENLABS_VOICE_ID` | Default voice ID for ElevenLabs |
|
| `ELEVENLABS_VOICE_ID` | Default voice ID for ElevenLabs |
|
||||||
| **Google Custom Search** | [Google Programmable Search Engine](https://programmablesearchengine.google.com/about/) produces links to pages |
|
| **Google Custom Search** | [Google Programmable Search Engine](https://programmablesearchengine.google.com/about/) produces links to pages |
|
||||||
| `GOOGLE_CLOUD_API_KEY` | Google Cloud API Key, used with the '/react' command - [Link to GCP](https://console.cloud.google.com/apis/credentials) |
|
| `GOOGLE_CLOUD_API_KEY` | Google Cloud API Key, used with the '/react' command - [Link to GCP](https://console.cloud.google.com/apis/credentials) |
|
||||||
| `GOOGLE_CSE_ID` | Google Custom/Programmable Search Engine ID - [Link to PSE](https://programmablesearchengine.google.com/) |
|
| `GOOGLE_CSE_ID` | Google Custom/Programmable Search Engine ID - [Link to PSE](https://programmablesearchengine.google.com/) |
|
||||||
| **Text-To-Image** | [Prodia](https://prodia.com/) is a reliable image generation service |
|
| **Text-To-Image** | [Prodia](https://prodia.com/) is a reliable image generation service |
|
||||||
| `PRODIA_API_KEY` | Prodia API Key - used with '/imagine ...' |
|
| `PRODIA_API_KEY` | Prodia API Key - used with '/imagine ...' |
|
||||||
| **Browse** | |
|
| **Browse** | |
|
||||||
| `PUPPETEER_WSS_ENDPOINT` | Puppeteer WebSocket endpoint - used for browsing, etc. |
|
| `PUPPETEER_WSS_ENDPOINT` | Puppeteer WebSocket endpoint - used for browsing, etc. |
|
||||||
| **Backend** | |
|
| **Backend** | |
|
||||||
| `BACKEND_ANALYTICS` | Semicolon-separated list of analytics flags (see backend.analytics.ts). Flags: `domain` logs the responding domain. |
|
| `BACKEND_ANALYTICS` | Semicolon-separated list of analytics flags (see backend.analytics.ts). Flags: `domain` logs the responding domain. |
|
||||||
|
| `HTTP_BASIC_AUTH_USERNAME` | Username for HTTP Basic Authentication. See the [Authentication](deploy-authentication.md) guide. |
|
||||||
|
| `HTTP_BASIC_AUTH_PASSWORD` | Password for HTTP Basic Authentication. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import type { NextRequest } from 'next/server';
|
||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
/**
|
||||||
|
* Middleware to protect with HTTP Basic Authentication.
|
||||||
|
*/
|
||||||
|
export function middleware(request: NextRequest) {
|
||||||
|
|
||||||
|
// Validate http basic auth configuration
|
||||||
|
if (!process.env.HTTP_BASIC_AUTH_USERNAME || !process.env.HTTP_BASIC_AUTH_PASSWORD) {
|
||||||
|
console.warn('HTTP Basic Authentication is enabled but not configured');
|
||||||
|
return new Response('Unauthorized/Unconfigured', unauthResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request client authentication if no credentials are provided
|
||||||
|
const authHeader = request.headers.get('authorization');
|
||||||
|
if (!authHeader?.startsWith('Basic '))
|
||||||
|
return new Response('Unauthorized', unauthResponse);
|
||||||
|
|
||||||
|
// Request authentication if credentials are invalid
|
||||||
|
const base64Credentials = authHeader.split(' ')[1];
|
||||||
|
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');
|
||||||
|
const [username, password] = credentials.split(':');
|
||||||
|
if (
|
||||||
|
!username || !password ||
|
||||||
|
username !== process.env.HTTP_BASIC_AUTH_USERNAME ||
|
||||||
|
password !== process.env.HTTP_BASIC_AUTH_PASSWORD
|
||||||
|
)
|
||||||
|
return new Response('Unauthorized', unauthResponse);
|
||||||
|
|
||||||
|
return NextResponse.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Response to send when authentication is required
|
||||||
|
const unauthResponse: ResponseInit = {
|
||||||
|
status: 401,
|
||||||
|
headers: {
|
||||||
|
'WWW-Authenticate': 'Basic realm="Secure big-AGI"',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: [
|
||||||
|
// Include root
|
||||||
|
'/',
|
||||||
|
// Include pages
|
||||||
|
'/(call|index|news|personas|link)(.*)',
|
||||||
|
// Include API routes (the most important part to block)
|
||||||
|
'/api(.*)',
|
||||||
|
// Note: this excludes _next, /images etc..
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
|
||||||
|
export default function handler(_: NextApiRequest, res: NextApiResponse) {
|
||||||
|
res.setHeader('WWW-authenticate', 'Basic realm="Private Area"')
|
||||||
|
res.statusCode = 401
|
||||||
|
res.end(`Auth Required.`)
|
||||||
|
}
|
||||||
@@ -48,6 +48,10 @@ export const env = createEnv({
|
|||||||
// Backend: Analytics flags (e.g. which hostname responds) for managed installs
|
// Backend: Analytics flags (e.g. which hostname responds) for managed installs
|
||||||
BACKEND_ANALYTICS: z.string().optional().transform(list => (list || '').split(';').filter(flag => !!flag)),
|
BACKEND_ANALYTICS: z.string().optional().transform(list => (list || '').split(';').filter(flag => !!flag)),
|
||||||
|
|
||||||
|
// Backend: HTTP Basic Authentication
|
||||||
|
HTTP_BASIC_AUTH_USERNAME: z.string().optional(),
|
||||||
|
HTTP_BASIC_AUTH_PASSWORD: z.string().optional(),
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onValidationError: error => {
|
onValidationError: error => {
|
||||||
|
|||||||
Reference in New Issue
Block a user