Providers
MongoDB Atlas
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.
Overview
Ahena works with one Atlas project: it checks the cluster your app uses is running and sized as
declared, keeps the database users and the project IP access list in line with ahena.config.ts,
creates a free M0 cluster (or, with explicit approval, a billed dedicated one), and generates a
small database module on the official mongodb driver. Your app connects to Atlas directly.
Ahena only calls the Atlas Administration API and is never in the query path.
Package: @ahena/provider-mongodb-atlas · Category: database · API: Atlas Administration API v2
(https://cloud.mongodb.com/api/atlas/v2, versioned media types 2023-01-01, 2024-08-05 for
clusters, 2024-11-13 for Flex clusters)
Capabilities: project, clusters, database-users, network-access, connection-metadata
Maturity: verified against a fake of the API; not yet verified against the real service.
Connection
Ahena signs in with an Atlas service account (OAuth 2.0 client credentials), which MongoDB
recommends over the legacy API keys. Ahena exchanges the client ID and secret for a one-hour
access token at POST https://cloud.mongodb.com/api/oauth/token and uses it for that operation
only.
| Field | Secret | |
|---|---|---|
MONGODB_ATLAS_CLIENT_ID |
yes | mdb_sa_id_… |
MONGODB_ATLAS_CLIENT_SECRET |
yes | Shown once when the secret is created. |
MONGODB_ATLAS_PROJECT_ID |
no | 24 hexadecimal characters (Atlas → Project Settings). Ahena lists the projects the account can see if it's missing. |
MONGODB_ATLAS_CLIENT_ID=… MONGODB_ATLAS_CLIENT_SECRET=… ahena connect mongodb-atlas -e production --set MONGODB_ATLAS_PROJECT_ID=…
API access list. If your organization requires an IP access list for the Administration API, tokens only work from addresses on the service account's own access list (creating a token doesn't, using it does). Atlas then refuses Ahena with HTTP 403; Ahena shows the address Atlas saw so you can add it, or an Organization Owner can lift the requirement.
API keys (HTTP Digest) aren't supported.
Permissions
Atlas permissions are project roles on the service account. Least privilege:
| Project role | Needed for |
|---|---|
| Project Read Only | validate, inspect, Doctor, lock and plan (always) |
| Project Database Access Admin | creating database users, setting their roles |
| Project Network Access Manager | adding IP access list entries |
| Project Cluster Creator | creating clusters |
| Project Cluster Manager | resizing a dedicated cluster |
Project Owner includes all of them. A read-only connection (Project Read Only only) is enough for Doctor and drift checks.
How Ahena checks them (permissionCheck: "checked"): after reading the project, validate()
reads the service account's own project roles (GET /groups/{id}/serviceAccounts/{clientId},
allowed for Project Read Only) and, if it may, its organization roles
(GET /orgs/{orgId}/serviceAccounts/{clientId}, Organization Read Only). Each scope is reported as
granted (database-users:write), unknown (database-users:write:unknown) or missing (absent). A
scope is reported missing only when both role lists were read and neither grants it, because an
Organization Owner can act in every project without a project role.
Capabilities
| Capability | Access | Verification | Changes | Refuses |
|---|---|---|---|---|
project |
read-only | |||
clusters |
writable | read-back | CONFIRMATION_REQUIRED (free M0), BILLABLE (dedicated create, resize) | deleting or pausing clusters, Flex/M2/M5 clusters, changing a free or Flex tier, resizing an auto-scaled cluster |
database-users |
writable | read-back (existence and roles; passwords are write-only) | CONFIRMATION_REQUIRED | deleting users, reading or changing an existing user's password |
network-access |
writable | read-back | CONFIRMATION_REQUIRED | 0.0.0.0/0 and anything broader than /8, deleting entries, IPv6 entries |
connection-metadata |
read-only |
Network: only cloud.mongodb.com (enforced). Inspect shows clusters (tier, cloud provider and
region, state, paused, MongoDB version, backup), database users (username, auth database, roles,
cluster scopes; never passwords), the IP access list (address, comment) and each cluster's SRV
hostname (never a user or password). ahena lock records clusters (tier, region, paused), users
with roles, and the access list.
Configure
database: {
provider: "mongodb-atlas",
project: "…", // optional: Doctor checks the connection uses this project
cluster: {
production: { name: "leo-prod", tier: "M10", provider: "AWS", region: "US_EAST_1" },
development: { name: "leo-dev", tier: "M0" },
},
databaseName: "leo", // default role database and the generated client's default
users: ["leo_app"], // or { username: "leo_ro", roles: [{ role: "read", db: "leo" }] }
accessList: { production: ["203.0.113.0/24", { cidr: "198.51.100.4", comment: "CI" }] },
},
Every value can be per environment. A cluster given by name only (cluster: "leo-prod") is
checked but never created. provider defaults to AWS and region to US_EAST_1; both are shown
in the plan.
| Change | Classification | Notes |
|---|---|---|
| Create a free M0 cluster | CONFIRMATION_REQUIRED | Atlas allows one free cluster per project; Ahena refuses a second. Creation is asynchronous: Ahena polls with bounded backoff until the cluster is IDLE, then re-reads. |
| Create a dedicated cluster (M10 and up) | BILLABLE | 3-node replica set with cloud backup on, tagged created_by=ahena. Billed hourly from creation; the plan shows a cost notice. |
| Resize a dedicated cluster | BILLABLE | Only an IDLE, unpaused cluster without compute auto-scaling. Ahena re-reads the cluster first and skips if its tier changed since review. |
| Create a database user | CONFIRMATION_REQUIRED | SCRAM user in admin, limited to the declared cluster, labelled created_by=ahena. Ahena generates a 32-character password and returns it only as the MONGODB_URI secret (MONGODB_URI_<NAME> for further users), stored encrypted. |
| Set a user's roles | CONFIRMATION_REQUIRED | Only when the config lists roles for that user. A user named without roles gets readWrite on databaseName (or readWriteAnyDatabase without one) when created, and is otherwise only checked for existence. |
| Add an IP access list entry | CONFIRMATION_REQUIRED | IPv4 address or canonical CIDR block. |
Refused outright: 0.0.0.0/0 and any block broader than /8, non-canonical blocks (Ahena names the
canonical one), IPv6 entries, Flex/M2/M5 clusters, deleting clusters, users or access list entries,
and pausing or resuming clusters.
Applying is idempotent: each action re-reads Atlas first and creates only what's absent. If a user already exists (for example after a lost response), Ahena doesn't create it again and can't return its password, because Atlas never returns passwords; the action is skipped with instructions.
Generate
ahena generate mongodb-atlas:
src/ahena/database/index.ts:mongoClient()(one cachedMongoClientfromMONGODB_URI),database.db(name?),database.collection<T>(name),database.ping(),database.close(),database.raw.env.example.mongodb-atlas:MONGODB_URIandMONGODB_DATABASE
The generated code imports only mongodb, never Ahena.
Limitations
- Service accounts only; API keys (HTTP Digest) aren't supported.
- Ahena never deletes or pauses clusters, deletes users or removes access list entries; do those in Atlas.
- Flex clusters are inspected but not created or changed; free and Flex tiers can't be changed through the API.
- Existing users' passwords are never read or rotated. Roles are managed only for users whose roles are listed.
- IPv6 access list entries, AWS security group entries, temporary entries, private endpoints, VPC peering, custom roles, X.509/LDAP/OIDC/AWS IAM users, backups, alerts and search indexes aren't managed.
- Resizing changes every electable and read-only spec to the same tier; per-shard sizes aren't supported.
- Each operation gets a fresh one-hour token; tokens aren't revoked afterwards (they expire).
- If a new cluster has no SRV hostname yet when its user is created, Ahena stores
MONGODB_PASSWORDinstead ofMONGODB_URI.
Manual steps
- Create the service account and give it the project roles above.
- If your organization requires an API access list, add the address Ahena reports to the service account's list.
- Remove
0.0.0.0/0from the project's IP access list once your app's addresses are listed. - Turn on cloud backup for production dedicated clusters if it's off.
- Resume paused clusters in Atlas.
Doctor checks
| Id | Severity | Meaning |
|---|---|---|
mongodb-atlas.credential |
PASS / FAIL | The service account can get a token and call the API (bad secret, API access list). |
mongodb-atlas.project |
PASS / FAIL | The project is reachable with the connection's project ID. |
mongodb-atlas.project.mismatch |
FAIL | database.project names a different project than the connection. |
mongodb-atlas.cluster |
PASS / WARNING / FAIL | The declared cluster exists, is IDLE and isn't paused (paused: FAIL in production). |
mongodb-atlas.cluster.undeclared |
INFO | No cluster declared; lists the project's clusters. |
mongodb-atlas.cluster.size |
WARNING | The tier differs from database.cluster.tier (BILLABLE fix, or MANUAL for free/Flex/auto-scaled). |
mongodb-atlas.cluster.tier |
WARNING | Production on a free or Flex cluster. |
mongodb-atlas.cluster.version |
INFO | MongoDB version. |
mongodb-atlas.cluster.backup |
WARNING | Cloud backup off on a production dedicated cluster. |
mongodb-atlas.users.<username> |
PASS / WARNING / FAIL | The user exists in admin with the configured roles; warns on admin roles. |
mongodb-atlas.access-list.open |
PASS / WARNING / FAIL | 0.0.0.0/0 (or ::/0) is on the access list (FAIL in production). |
mongodb-atlas.access-list |
PASS / WARNING | Configured entries are present. |
Disconnect behavior
Removes the connection and the client ID and secret Ahena stored. Ahena can't revoke a service account: delete it (or its secret) in Atlas → Organization → Access Manager → Applications → Service Accounts. Clusters, database users and the IP access list stay in Atlas.
Set up step by step
Create the service account. In Atlas, open your organization's Access Manager → Applications → Service Accounts → Create Service Account. Give it a name, the Organization Member organization permission and a secret expiration, then copy the client ID (
mdb_sa_id_…) and the client secret; Atlas shows the secret once.Minimum permissions. In the project, open Project Identity & Access → Applications, add the service account and grant Project Read Only plus the roles for what Ahena should change: Project Database Access Admin (users), Project Network Access Manager (access list), Project Cluster Creator (clusters), Project Cluster Manager (resizing). If your organization requires an API access list, add the address Ahena reports to the service account's API Access List.
Connect.
MONGODB_ATLAS_CLIENT_ID=… MONGODB_ATLAS_CLIENT_SECRET=… ahena connect mongodb-atlas -e development --set MONGODB_ATLAS_PROJECT_ID=… MONGODB_ATLAS_CLIENT_ID=… MONGODB_ATLAS_CLIENT_SECRET=… ahena connect mongodb-atlas -e production --set MONGODB_ATLAS_PROJECT_ID=…Use a separate project (and ideally a separate service account) per environment.
Verify the connection.
ahena inspect mongodb-atlas -e developmentlists the project, clusters, users with roles and the access list.Run Doctor.
ahena doctor -e production(and-e development).Plan. Add the
databasesection above toahena.config.ts, thenahena plan -e development(orahena configure mongodb-atlas -e developmentto plan and apply this provider only).Apply.
ahena apply -e development. Users, access list entries and a free M0 cluster need confirmation; a dedicated cluster or a resize is BILLABLE, so with--yesit also needs--allow-billable.Verify. Ahena re-plans after applying;
ahena plan -e developmentshould show no Atlas changes andahena doctor -e developmentshould pass.ahena env secrets developmentlistsMONGODB_URI(masked); read it withahena env reveal development MONGODB_URI. Thenahena generate mongodb-atlas -e development.Troubleshooting.
Symptom Cause Fix "Atlas rejected the service account credentials" Wrong, expired or deleted secret Create a new secret for the service account and reconnect. "Atlas refused Ahena's address for this service account" (403) The organization requires an API access list Add the address shown to the service account's API Access List. "The service account can't open that Atlas project" It isn't added to the project Add it under Project Identity & Access → Applications. "…doesn't have the Atlas project role this needs (Project …)" at apply Missing project role (Atlas answers 401 USER_UNAUTHORIZED) Grant the named role, or Project Owner. "Atlas needs a payment method" Dedicated cluster in an organization without billing Add a payment method in Atlas, or use tier: "M0"."Atlas allows one free (M0) cluster per project" The project already has one Use it, or a different project. A user is skipped as "already exists" The user was created earlier; Atlas never returns passwords Edit its password in Atlas (Database Access), then ahena env set <environment> MONGODB_URI.MONGODB_PASSWORDinstead ofMONGODB_URIThe new cluster wasn't ready yet Copy the SRV connection string from Atlas → Connect and ahena env set <environment> MONGODB_URI.Cluster shows CREATING or UPDATING Atlas is still working Run Doctor again in a few minutes. Disconnect and revoke.
ahena disconnect mongodb-atlas -e production, then delete the service account or its secret in Atlas (Organization → Access Manager → Applications → Service Accounts).