diff --git a/AGENTS.md b/AGENTS.md index c64298c509..14a73c0f3e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,44 @@ bottom. - Docs writing: the Diátaxis framework digest at `agents/docs/diataxis/`, and the `write-docs` skill for Agenta style, voice, and structure. +## Branching and PRs with GitButler + +This repo may be in GitButler workspace mode (current branch `gitbutler/workspace`). +If so, use the `but` CLI instead of raw `git branch`/`git commit`: + +- `but status` shows lanes and unassigned changes; `but branch new ` creates a + parallel lane; add `--anchor ` to stack on a parent. +- `but commit -m "..."` commits the uncommitted changes to that branch. + Pre-commit hooks (ruff, prettier, gitleaks) run; if a hook reformats files the + commit aborts — just rerun it. Changes belonging to another lane's commits stay + unassigned rather than being folded in. +- `but pr new` needs interactive forge auth; use `but push ` then + `gh pr create --head --base ` instead. For stacked PRs, + set `--base` to the parent branch so each PR shows only its own diff. +- To update an already-committed file, `but absorb ` amends it into the right + commit; force-push with `but push -f`. +- To commit to a specific branch in a stack, stage the files to it first + (`but rub `), then `but commit --only`. `but commit` + alone sweeps ALL uncommitted changes into that branch. + +### Hard-won gotchas (don't relearn these) + +- **GitButler series need linear history.** A stack of branches connected by + `git merge` commits (e.g. branches synced by merging a release in) can collapse + to a single series (the tip) when unapplied/re-applied — the intermediate + branches stop being addressable and you can't `but commit` to them. Prefer + GitButler's own stacking over merging branches into each other. +- **Don't sync a behind lane with `unapply` → `git branch -f origin/` → + `apply`.** Pointing a series at a merge-based origin ref flattens the stack. + There is no clean "fast-forward this series to its own remote" in the CLI when + origin is merge-based and ahead. +- **`but pull` rebases applied branches on the TARGET (main), not on each + branch's own upstream.** It will not advance a series to `origin/`. +- **Recovery: `but oplog list` then `but oplog restore `** rewinds the whole + workspace (including uncommitted changes) to any prior snapshot — this is how + you undo a botched unapply/apply and get a collapsed stack's series back. Take + a `but oplog snapshot -m "..."` before risky operations. + ## Before committing - Frontend changes: run `pnpm lint-fix` within the `web` folder. Details: `web/AGENTS.md`. diff --git a/docs/docs/administration/access-control/01-organizations.mdx b/docs/docs/administration/access-control/01-organizations.mdx index 53cc0c4c55..5f8d168ff2 100644 --- a/docs/docs/administration/access-control/01-organizations.mdx +++ b/docs/docs/administration/access-control/01-organizations.mdx @@ -23,7 +23,7 @@ Organization ### Creating an Organization -Organizations are created during signup or from the organization switcher. +Organizations are created during signup or from the organization switcher. This applies to Agenta Cloud and to self-hosted deployments of both editions; self-hosters can restrict who creates organizations with [`AGENTA_ACCESS_ALLOWED_OWNER_EMAILS`](/self-host/guides/restrict-organization-creation). Role-based access control and domain verification remain plan-gated features. ### Switching Organizations diff --git a/docs/docs/misc/01-opensource.mdx b/docs/docs/misc/01-opensource.mdx index 3b739fe64b..b977a13104 100644 --- a/docs/docs/misc/01-opensource.mdx +++ b/docs/docs/misc/01-opensource.mdx @@ -39,6 +39,7 @@ Here's what's available in each version: | Human Evaluation | ✅ | ✅ | | Automatic Evaluation | ✅ | ✅ | | Custom Workflows | ✅ | ✅ | +| Multiple Organizations | ✅ | ✅ | | Role-Based Access Control | ❌ | ✅ | | Custom SSO | ❌ | ✅ | | Support | ❌ | ✅ | @@ -66,7 +67,7 @@ Yes, there is no risk of executing any enterprise-restricted code when using the ### What features remain commercial-only? All functional features for building and evaluating LLM applications are now open source. The commercial version focuses on enterprise and team needs: -- Team Management: Role-based access control and multi-team organizations +- Team Management: Role-based access control, SSO, and domain verification - Support: Professional support with SLAs - Enterprise Features: Custom SSO and other enterprise-specific capabilities diff --git a/docs/docs/self-host/01-quick-start.mdx b/docs/docs/self-host/01-quick-start.mdx index e8a1dc1f60..2c70b8fc01 100644 --- a/docs/docs/self-host/01-quick-start.mdx +++ b/docs/docs/self-host/01-quick-start.mdx @@ -36,6 +36,10 @@ docker compose -f hosting/docker-compose/oss/docker-compose.gh.yml --env-file ho 4. Access Agenta at `http://localhost`. +:::info Sign-ups are open by default +Anyone who can reach your instance can sign up and gets their own organization. If the instance is exposed beyond a trusted network, see [Restrict Sign-ups and Organization Creation](/self-host/guides/restrict-organization-creation). +::: + ## Using a Custom Port To use a different port (e.g., 90): diff --git a/docs/docs/self-host/02-configuration.mdx b/docs/docs/self-host/02-configuration.mdx index 6440a51974..86ff794d47 100644 --- a/docs/docs/self-host/02-configuration.mdx +++ b/docs/docs/self-host/02-configuration.mdx @@ -42,6 +42,12 @@ This key has no env-var or `env.py` equivalent. ## Agenta — access +The first four variables (allowed/blocked domains and emails, allowed owner +emails) apply to both the open source and Enterprise editions. See +[Restrict Sign-ups and Organization Creation](/self-host/guides/restrict-organization-creation) +for how they behave. The plan and role variables are Enterprise-only; see +[Dynamic Access Controls](/self-host/dynamic-access-controls). + | Env var | env.py path | values.yaml path | |---|---|---| | `AGENTA_ACCESS_ALLOWED_DOMAINS` | `agenta.access.allowed_domains` | `agenta.access.allowedDomains` | diff --git a/docs/docs/self-host/03-upgrading.mdx b/docs/docs/self-host/03-upgrading.mdx index c22c84debe..242fac50ba 100644 --- a/docs/docs/self-host/03-upgrading.mdx +++ b/docs/docs/self-host/03-upgrading.mdx @@ -11,6 +11,10 @@ Agenta follows semantic versioning with new releases every week. Stay updated by - Following our [GitHub repository](https://github.com/Agenta-AI/agenta) releases - Reading our [changelog](/changelog) for detailed updates +:::caution Upgrading an open source instance to the multi-organization release +The multi-organization release flips OSS from invite-only to open signup. If your instance is reachable beyond a trusted network, set `AGENTA_ACCESS_ALLOWED_OWNER_EMAILS` (and optionally `AGENTA_ACCESS_ALLOWED_DOMAINS`) before upgrading. See [Migrate to Multi-Organization OSS](/self-host/upgrades/multi-org-migration). +::: + ## Standard Upgrade Process For most upgrades, follow these steps to update your Agenta instance: diff --git a/docs/docs/self-host/04-dynamic-access-controls.mdx b/docs/docs/self-host/04-dynamic-access-controls.mdx index 347cab16ea..a0a9096b4a 100644 --- a/docs/docs/self-host/04-dynamic-access-controls.mdx +++ b/docs/docs/self-host/04-dynamic-access-controls.mdx @@ -8,7 +8,15 @@ description: Override the built-in plans, entitlements, and role catalogs at run Agenta EE ships with code-default plans, entitlements, and role catalogs. Operators can override any of these at runtime by setting JSON environment -variables. This page documents the **access** layer: +variables. + +The variables on this page (plans, entitlements, roles) are **Enterprise-only**. +The simpler sign-up and organization-creation controls +(`AGENTA_ACCESS_ALLOWED_DOMAINS`, `AGENTA_ACCESS_ALLOWED_OWNER_EMAILS`, and the +block lists) work in **both editions**; they are covered in +[Restrict Sign-ups and Organization Creation](/self-host/guides/restrict-organization-creation). + +This page documents the **access** layer: - `AGENTA_ACCESS_PLANS` — plan slugs and per-plan entitlement controls (flags, counters, gauges, throttles). diff --git a/docs/docs/self-host/guides/06-restrict-organization-creation.mdx b/docs/docs/self-host/guides/06-restrict-organization-creation.mdx index 15d423d936..aeeec33f72 100644 --- a/docs/docs/self-host/guides/06-restrict-organization-creation.mdx +++ b/docs/docs/self-host/guides/06-restrict-organization-creation.mdx @@ -1,29 +1,64 @@ --- -title: Restrict Organization Creation -sidebar_label: Restrict Org Creation -description: Control which users can create organizations in your self-hosted Agenta Enterprise deployment. +title: Restrict Sign-ups and Organization Creation +sidebar_label: Restrict Access +description: Control who can sign up and who can create organizations in your self-hosted Agenta deployment, in both the open source and Enterprise editions. --- -import Admonition from "@theme/Admonition"; +By default, anyone who can reach your Agenta instance can sign up and gets their own organization. This guide shows how to close that down. All settings on this page work in both the open source and Enterprise editions. - -Organization creation restriction requires an Agenta Enterprise license. Book a demo or contact our team to get started. - +## Restrict who can create organizations -Set `AGENTA_ORG_CREATION_ALLOWLIST` to a comma-separated list of emails allowed to create organizations. +Set `AGENTA_ACCESS_ALLOWED_OWNER_EMAILS` to a comma-separated list of emails allowed to create organizations: ```bash -AGENTA_ORG_CREATION_ALLOWLIST=admin@company.com,ops@company.com +AGENTA_ACCESS_ALLOWED_OWNER_EMAILS=admin@company.com,ops@company.com ``` -When this variable is set, only the listed emails can create organizations. Everyone else must be invited to an existing one. When it is not set, any user can create organizations (the default). +When this variable is set, only the listed emails get an organization on signup and can create new ones. Everyone else must be invited to an existing organization. When it is not set, any user who signs up gets their own organization (the default). -Restart your Agenta deployment after changing this variable. +The legacy names `AGENTA_ORG_CREATION_ALLOWLIST` and `AGENTA_ACCESS_ORG_CREATION_ALLOWLIST` are still parsed as aliases. :::caution First user must be in the allowlist The first user to sign up needs to be in the allowlist. Otherwise, they will not be able to create the initial organization. ::: +## Restrict who can sign up + +To limit sign-ups to your own domains, set `AGENTA_ACCESS_ALLOWED_DOMAINS`: + +```bash +AGENTA_ACCESS_ALLOWED_DOMAINS=company.com +``` + +Subdomains match too (`user@team.company.com` is allowed by `company.com`). Any email outside the listed domains is denied at sign-in and sign-up. + +To block specific addresses or domains instead, use the block lists: + +```bash +AGENTA_ACCESS_BLOCKED_EMAILS=spammer@example.com +AGENTA_ACCESS_BLOCKED_DOMAINS=example.org +``` + +When `AGENTA_ACCESS_ALLOWED_DOMAINS` is set, the block lists for domains are not consulted; the allowlist wins. + +Restart your Agenta deployment after changing any of these variables. + ## How restricted users join -Users not in the allowlist can still sign up, but they will not have an organization. You need to either enable auto-join for a domain from **Settings > Access & Security**, or invite users from **Settings > Workspace > Members** before they sign up. +Users who pass the sign-up checks but are not allowed to create an organization can still sign in. They have no organization until someone invites them: + +1. As an organization member with invite rights, go to **Settings > Workspace > Members** and invite their email. +2. The user accepts the invitation and becomes a member of that organization. + +On Enterprise, you can also enable auto-join for a verified domain from **Settings > Access & Security**, so users from that domain join the organization automatically on signup. + +## Reference + +| Variable | Effect | +|---|---| +| `AGENTA_ACCESS_ALLOWED_OWNER_EMAILS` | Only listed emails can create organizations | +| `AGENTA_ACCESS_ALLOWED_DOMAINS` | Only listed domains (and subdomains) can sign up | +| `AGENTA_ACCESS_BLOCKED_DOMAINS` | Listed domains cannot sign up | +| `AGENTA_ACCESS_BLOCKED_EMAILS` | Listed emails cannot sign up | + +See the [configuration reference](/self-host/configuration) for the full list of environment variables. diff --git a/docs/docs/self-host/upgrades/multi-org-migration.mdx b/docs/docs/self-host/upgrades/multi-org-migration.mdx new file mode 100644 index 0000000000..8ca94d6f6d --- /dev/null +++ b/docs/docs/self-host/upgrades/multi-org-migration.mdx @@ -0,0 +1,45 @@ +--- +title: Migrate to Multi-Organization OSS (v0.104.0) +sidebar_label: pre-v0.104.0 → v0.104.0 (multi-org OSS) +description: 'What changes for self-hosted OSS deployments upgrading to v0.104.0, when Agenta becomes multi-organization: open signup replaces invite-only, membership rows are backfilled, and the access env vars are now enforced. Covers what to set before upgrading.' +--- + +:::info When you need this guide +You're on this page if you run a self-hosted **OSS** Agenta instance on a version before **v0.104.0**. v0.104.0 removes the single-organization limit from OSS: every allowed user gets their own organization on signup, organizations can be created, renamed, transferred, and deleted from the UI, and the `AGENTA_ACCESS_*` variables are enforced the same way as in EE. EE deployments are unaffected; their behavior already worked this way. +::: + +## The one thing to do before upgrading + +**Your instance flips from invite-only to open signup.** Before v0.104.0, only the first user could sign up freely; everyone else needed an invitation to your single organization. After v0.104.0, anyone who can reach your instance can sign up and gets their own organization. + +If your instance is reachable beyond a trusted network, set access controls in your environment file **before** upgrading: + +```bash +# Only these emails can create organizations; everyone else needs an invitation +AGENTA_ACCESS_ALLOWED_OWNER_EMAILS=admin@company.com + +# Optional: only these domains can sign up at all +AGENTA_ACCESS_ALLOWED_DOMAINS=company.com +``` + +See [Restrict Sign-ups and Organization Creation](/self-host/guides/restrict-organization-creation) for all options. If your instance is on a private network or open signup is what you want, there is nothing to do. + +## What the migration does to your data + +The schema migrations run as part of the normal [upgrade process](/self-host/upgrading). For existing deployments they: + +- Create the `organization_members`, `workspace_members`, and `project_members` tables and backfill them: the organization owner becomes an `owner` member, and every user who joined through an invitation becomes a member with the role from their invitation. +- Keep your existing organization as a normal organization. Its members, projects, and data are untouched; it just stops being special. +- Tighten a few constraints (`api_keys.project_id`, `projects.organization_id`/`workspace_id` become required). API keys created before project scoping existed are removed; they could not authenticate anything. +- Drop the legacy tables of the old app-centric architecture (`app_db`, `app_variants`, old `testsets`, old evaluation tables, and similar). Their data was migrated to the current entities by earlier releases. If you skipped many releases, upgrade through them in order. + +## What changes day to day + +- Users in your organization see an organization switcher and a "New organization" entry in the sidebar. Whether new organizations can actually be created depends on `AGENTA_ACCESS_ALLOWED_OWNER_EMAILS`. +- Organization owners can rename, transfer, and delete organizations from the sidebar. +- Inviting users works as before. Accepted invitations now create explicit membership records. +- Role-based access control, SSO, and domain verification remain EE features. OSS roles stay coarse (owner and member). + +## Rollback + +The membership backfill and constraint changes are reversible with `alembic downgrade`, but the legacy-table drop is not. Take a database backup before upgrading, as with any release. diff --git a/docs/docs/self-host/upgrades/oss-to-ee-switch.mdx b/docs/docs/self-host/upgrades/oss-to-ee-switch.mdx new file mode 100644 index 0000000000..3a30cc0865 --- /dev/null +++ b/docs/docs/self-host/upgrades/oss-to-ee-switch.mdx @@ -0,0 +1,127 @@ +--- +title: Switch a Self-Hosted Deployment from OSS to EE (v0.104.0) +sidebar_label: OSS → EE +description: 'How to switch an existing self-hosted Agenta OSS deployment to EE in place on v0.104.0, keeping all your data: stop the stack, point EE at your existing databases, and start it again. The EE migration creates the extra tables and backfills the EE-only data on first run.' +--- + +:::info When you need this guide +You run a self-hosted **OSS** Agenta deployment on **v0.104.0** or later and want to move to **EE** without losing data. EE reuses the same core schema as OSS and adds a few tables of its own. Switching keeps your organizations, members, projects, and traces; the first EE start creates the extra tables and backfills the EE-only data. +::: + +## How the switch works + +OSS and EE store data in databases whose names carry the edition: `agenta_oss_core` / `agenta_oss_tracing` for OSS, `agenta_ee_core` / `agenta_ee_tracing` for EE. Switching the license alone would make EE look for `agenta_ee_*`, find nothing, and start empty. + +So the switch is one idea: **run EE against your existing OSS databases.** When it starts, the EE migration runs against that data, creates the EE-only tables if they are missing, and backfills the EE-only data. Running it a second time changes nothing. + +The whole procedure is the same whether you run with Docker Compose or Kubernetes: + +1. Stop the deployment. +2. Set the license to EE, point it at your existing databases, and add any EE-only settings you need. +3. Start it again. + +Do this without removing any volumes, so your data is reused. + +## Before you start + +- **Back up your databases.** The switch creates and backfills tables; take a backup first, as with any upgrade. +- **Run as OSS on v0.104.0 first.** This is required. Start your deployment once as OSS on v0.104.0 and let its migrations finish before switching. That run brings the database to the shared alignment point that the EE migrations expect. Switching from an older OSS database makes the EE run apply OSS-specific legacy steps it cannot complete, and it fails. +- **Have EE image access.** EE images are private; make sure your registry credentials are configured. + +:::caution Align before you switch +The EE migrations only pick up an OSS database at the alignment point. Always upgrade and run as OSS on v0.104.0 first, confirm it started cleanly, then do the switch. Skipping this step fails the EE migration partway through. +::: + +## Docker Compose + +Reuse your **existing** OSS env file. Keeping the same Compose project name in it is what reuses the same database volume. + +There are two ways to point EE at your existing `agenta_oss_*` databases. Pick one for step 3: + +- **Database prefix (simplest).** One value covers all three: `POSTGRES_DB_PREFIX=agenta_oss`. EE resolves `agenta_oss_core`, `agenta_oss_tracing`, and `agenta_oss_supertokens` from it. +- **Explicit connection URIs.** Set `POSTGRES_URI_CORE`, `POSTGRES_URI_TRACING`, and `POSTGRES_URI_SUPERTOKENS` to the full `agenta_oss_*` connection strings. Explicit URIs always win over the prefix. + +1. **Stop the stack** (keep your volumes): + + ```bash + ./hosting/docker-compose/run.sh --oss --down + ``` + +2. **Move your env file into the EE folder.** `run.sh --ee` looks for the env file under the EE folder, so move (or copy) the OSS one there: + + ```bash + mv hosting/docker-compose/oss/.env.oss.gh hosting/docker-compose/ee/.env.ee.gh + ``` + +3. **Edit that env file.** Change two things, and make sure the project name is pinned: + + ```bash + AGENTA_LICENSE=ee + POSTGRES_DB_PREFIX=agenta_oss # prefix option; or set the POSTGRES_URI_* values instead + + # Keep the same Compose project as before so the existing volume is reused. + # If this line was commented out, set it to the name your stack ran under. + COMPOSE_PROJECT_NAME=agenta-oss-gh + ``` + + `COMPOSE_PROJECT_NAME` decides which database volume is used. Leaving it as your OSS value is what makes the switch happen in place; pointing it elsewhere starts against an empty database. + + Add any EE-only variables you need in the same file. + +4. **Start EE with that env file:** + + ```bash + ./hosting/docker-compose/run.sh --ee --env-file .env.ee.gh + ``` + +The EE migration runs on start. When it finishes, your existing data is served by EE. + +If you use an external PostgreSQL instead of the bundled one, there is no volume to worry about: the database override alone is enough. + +## Kubernetes (Helm) + +Edit your values file: set the license to EE and point at your existing `agenta_oss_*` databases. There are two ways to point at them, depending on whether you use the bundled PostgreSQL or an external one. Pick one. + +**Option A: bundled PostgreSQL (set the database names).** Override the names so EE uses your existing databases instead of creating empty `agenta_ee_*` ones: + +```yaml +agenta: + license: ee + +postgresql: + databases: + core: agenta_oss_core + tracing: agenta_oss_tracing + supertokens: agenta_oss_supertokens +``` + +**Option B: external PostgreSQL (set the connection URIs).** When the bundled PostgreSQL is disabled, EE reads the URIs directly: + +```yaml +agenta: + license: ee + +postgresql: + enabled: false + external: + uriCore: postgresql+asyncpg://username:password@your-host:5432/agenta_oss_core + uriTracing: postgresql+asyncpg://username:password@your-host:5432/agenta_oss_tracing + uriSupertokens: postgresql://username:password@your-host:5432/agenta_oss_supertokens +``` + +Add any EE-only values you need in the same file. Then upgrade the release; the migration runs as a post-upgrade job: + +```bash +helm upgrade --install agenta agenta/agenta -f +``` + +The post-upgrade migration job runs against your existing data automatically. + +## After the switch + +- All organizations, members, projects, and traces are unchanged. +- The EE-only tables are populated, and EE features become available. + +## Rollback + +The switch adds tables and rows; it does not change or remove your OSS data. To go back, stop EE and start OSS again against the same databases. Take a backup before switching, as with any upgrade.