Core concepts
Environments
Uses the Ahena CLI (beta). Install it with npm install -g @ahena/cli, or prefix commands with npx @ahena/cli. See Installation. The dashboard covers projects, connections, Doctor, the Stack Graph, plans and approvals without it.
Each project starts with development and production. Add more with
ahena env create Staging --kind staging or from the dashboard. Kinds: local,
development, preview, staging, production. Creating a production environment needs an
admin.
Every environment has its own provider connections and secrets. Nothing is shared: a development Stripe key can't reach production by accident.
Production is stricter
| Action | development / staging | production |
|---|---|---|
| Connect or configure providers | developer+ | admin+ |
| Write secrets | developer+ | admin+ (and a confirmation) |
| Reveal secret values | developer+ | admin+ |
| Agent (MCP) changes | SAFE and confirmation-required | SAFE only without your approval |
| Approve changes that aren't SAFE | the CLI (billable/destructive: dashboard) | the dashboard, signed in (approvals) |
| Continuous Doctor (monitoring) | off until a developer+ turns it on | on, daily, by default; only admin+ change it |
Live credentials make an environment production
The kind you give an environment is a label. What Ahena's rules use is the effective kind:
production when the kind is production, or when any connection in it holds a live
credential. A "development" environment with a live Stripe key (sk_live_… or rk_live_…)
gets every production rule in the table above, and the dashboard, the plan and the approval
pages say why: Treated as production: holds a live Stripe key.
- Ahena learns it from the provider when it connects or verifies the credential
(
ValidationResult.live), and keeps the marker with the connection's non-secret metadata. A failed or interrupted verification keeps what an earlier one reported, so an outage can't lower the protection. Disconnecting the connection (an admin's job now) removes it. - Today only Stripe can tell for certain (its key prefix). Other providers' credentials don't say whether they reach production data, so Ahena doesn't guess; use the production kind.
- Connecting a live credential to an environment that isn't already production needs an admin.
For anyone else Ahena removes the credential it just stored and refuses
(
live_credential_requires_admin), so a developer can't make an environment production by connecting a key. - Providers themselves still see the kind you gave (for example Stripe's verification checks
and production CORS rules apply only to
productionenvironments). - The API returns both:
kindandeffectiveKind, plustreatedAsProductionwith the reason.
Rename, change the kind, delete
In the dashboard (the environment's Environment settings) or the API
(PATCH / DELETE /v1/orgs/:org/projects/:project/environments/:env):
| Change | Who |
|---|---|
Rename (the slug never changes: ahena.config.ts and the CLI use it) |
developer+ |
| Change the kind between non-production kinds | developer+, not an agent session |
| Change the kind to or from production | admin+, not an agent session |
| Delete an environment | admin+, not an agent session; only with no connected provider, no secrets and no plan applying |
Every change is audited (environment.updated with the old and new values,
environment.deleted). Deleting removes the environment's plans, Doctor runs and approval
requests; the audit log keeps every event, and nothing at any provider is touched. An
environment holding a live credential stays production whatever kind you choose.
Separation checks
Doctor flags a test-mode key in production (FAIL), a live key outside production (WARNING; if it's a connection's key, the environment is already treated as production) and the same secret value in production and another environment (WARNING). Values are compared in memory on the server; Doctor reports only secret names, never values. The cross-environment comparison runs only when the person running Doctor may reveal production secrets (owners and admins, not agent sessions or CI tokens): otherwise which of your values equal a production one would tell you production values. Other runs say so (INFO), and the environment's latest picture keeps the last admin run's finding.
Monitoring
Each environment has its own continuous Doctor settings (on/off, hourly or daily, who's
emailed) and its own scheduled results: runs use that environment's connections and
credentials only, and drift compares that environment's ahena.lock entry. Production is
monitored daily unless an admin turns it off; other environments aren't until someone turns
them on. See doctor.md.