Documentation menu

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 cached MongoClient from MONGODB_URI), database.db(name?), database.collection<T>(name), database.ping(), database.close(), database.raw
  • .env.example.mongodb-atlas: MONGODB_URI and MONGODB_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_PASSWORD instead of MONGODB_URI.

Manual steps

  1. Create the service account and give it the project roles above.
  2. If your organization requires an API access list, add the address Ahena reports to the service account's list.
  3. Remove 0.0.0.0/0 from the project's IP access list once your app's addresses are listed.
  4. Turn on cloud backup for production dedicated clusters if it's off.
  5. 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

  1. 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.

  2. 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.

  3. 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.

  4. Verify the connection. ahena inspect mongodb-atlas -e development lists the project, clusters, users with roles and the access list.

  5. Run Doctor. ahena doctor -e production (and -e development).

  6. Plan. Add the database section above to ahena.config.ts, then ahena plan -e development (or ahena configure mongodb-atlas -e development to plan and apply this provider only).

  7. 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 --yes it also needs --allow-billable.

  8. Verify. Ahena re-plans after applying; ahena plan -e development should show no Atlas changes and ahena doctor -e development should pass. ahena env secrets development lists MONGODB_URI (masked); read it with ahena env reveal development MONGODB_URI. Then ahena generate mongodb-atlas -e development.

  9. 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_PASSWORD instead of MONGODB_URI The 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.
  10. 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).