Quickstart
Install the CLI, create a project, allow your device, fetch branch URLs, connect an app, and run your first migration — all in under five minutes.
This is the fastest path from zero to a working Postgres branch. By the end of this guide, you'll have a provisioned database, your device allowlisted, connection URLs in your .env, and a Prisma migration running against your AxiomDB branch.
1. Install the CLI
npm install -g axiomdb-cli
axm -hThe package exposes axm as the short binary. The longer axiom binary remains available for backward compatibility with existing scripts and automation.
What the CLI does under the hood
The axm CLI is a Rust binary compiled for your platform and distributed through npm for cross-platform compatibility. When you run axm, it:
- Reads the local session token from
~/.axiomdb/. - Constructs an HTTPS request to the AxiomDB Gateway at
api.axiomdb.squareexp.com. - Attaches a PASETO v4 bearer token for authentication.
- Sends the request to the appropriate
/api/v1/*endpoint. - Parses and formats the response for terminal display.
CLI version and updates
Check your current version:
axm --versionUpdate to the latest version:
npm update -g axiomdb-cli2. Sign in
axm loginThe CLI opens your browser for Square IdP authentication using OAuth2 PKCE (Proof Key for Code Exchange). This is a public client flow that doesn't require a client secret — making it safe for terminal use.
How the PKCE flow works
┌─────────┐ ┌─────────┐ ┌──────────────┐
│ axm │ │ Browser │ │ Square IdP │
│ CLI │ │ │ │ │
└────┬────┘ └────┬────┘ └──────┬───────┘
│ 1. Generate │ │
│ code_verifier + │ │
│ code_challenge │ │
│ │ │
│ 2. Start local │ │
│ loopback server │ │
│ on random port │ │
│ │ │
│ 3. Open browser ──▶ 4. Redirect to ──▶ │
│ with auth URL │ IdP authorize │
│ │ endpoint │
│ │ │
│ │ 5. User authenticates
│ │ ◀────────────────┘
│ │
│ │ 6. Redirect to loopback
│ 7. Receive code ◀─┘ with auth code
│ │
│ 8. Exchange code │
│ + verifier for ──────────────────────▶ 9. Validate
│ tokens │ challenge
│ │ issue tokens
│ 10. Store session ◀───────────────────── 11. Return
│ locally │ PASETO tokens
│ │
▼ │
"AxiomDB OAuth │
complete" │Verifying your session
After signing in, verify your identity:
axm whoami
axm -liThe CLI stores a local session token and uses the active gateway configured for your environment. The session token is a PASETO v4 public token with Ed25519 signatures, with a default access TTL of 15 minutes and a refresh TTL of 7 days.
Password login is deprecated
Password login remains available only for legacy automation that passes --email and --password. All human users should authenticate through the browser-based OAuth2 PKCE flow.
3. Create a project
axm projects create --name "Square Experience" --app-key square_experience --env mainProject creation provisions the first branch:
project: Square Experience
branch: main
db: sq_square_experience_mainWhat happens during project creation
The gateway dispatches a provisioning command through the Redis queue to square-dbctl, which executes:
-
Database creation:
CREATE DATABASE sq_square_experience_main; -
Role provisioning:
CREATE ROLE square_experience_main_owner WITH LOGIN PASSWORD '***' CREATEDB; CREATE ROLE square_experience_main_rw WITH LOGIN PASSWORD '***'; CREATE ROLE square_experience_main_ro WITH LOGIN PASSWORD '***'; -
Permission grants:
GRANT ALL PRIVILEGES ON DATABASE sq_square_experience_main TO square_experience_main_owner; GRANT CONNECT ON DATABASE sq_square_experience_main TO square_experience_main_rw; GRANT CONNECT ON DATABASE sq_square_experience_main TO square_experience_main_ro; -
PgBouncer userlist update — Adds the runtime role to the PgBouncer authentication file.
-
Credential storage — Writes the generated URLs to the encrypted secret file at
~/.creds/zone.envwith namespaced keys:DATABASE_URL_SQUARE_EXPERIENCE_MAIN="postgresql://square_experience_main_rw:***@db.squareexp.com:6432/sq_square_experience_main?sslmode=require" DIRECT_URL_SQUARE_EXPERIENCE_MAIN="postgresql://square_experience_main_owner:***@db.squareexp.com:5432/sq_square_experience_main?sslmode=require" -
Audit logging — Records
project.createdandbranch.createdevents.
The app_key parameter
The app_key becomes part of database names, role names, environment variable keys, and branch URL paths. Keep it:
- Short — It appears in every URL and database name.
- Lowercase — PostgreSQL normalizes identifiers to lowercase.
- Stable — Changing it after creation would require renaming databases and roles.
- Unique per environment — The
(app_key, env)pair must be unique across all projects.
4. Select the project
axm projects list
axm projects use <project-id>With an active project, branch commands can omit the project ID:
axm branches list # Uses active project
axm branches urls --name main # Uses active projectWithout an active project, the CLI prints an actionable message:
No active project selected.
Run `axm projects use <project-id>` to set one.Listing projects
axm projects listOutput:
ID NAME APP_KEY ENV STATUS BRANCHES
proj_a1b2 Square Experience square_experience main active 3
proj_c3d4 Admin Dashboard admin4 dev active 1Viewing the current project
axm projects current5. Allow your device
Open the console Network page and press My IP, then Save JSON. This stores a CIDR rule like:
{
"policy": {
"apply": false,
"mode": "restricted"
},
"rules": [
{
"cidr": "203.0.113.10/32",
"expires_in": "7d",
"label": "My current IP",
"ports": "both",
"scope": "project"
}
]
}Or use the CLI
axm network allow --current
axm -ne add --currentUnderstanding network modes
| Mode | Runtime 6432 | Direct 5432 | When to use |
|---|---|---|---|
restricted | Allowlisted only | Allowlisted only | Default. Most secure. |
public_runtime | Public | Allowlisted only | When app traffic comes from changing IPs (serverless, edge). |
public_all | Public | Public | Temporary debugging only. Requires owner role and typed confirmation. |
Restricted mode is the default. Only explicit CIDRs can reach runtime or direct Postgres ports.
How the allowlist works
When you add a CIDR rule, the gateway:
- Stores the rule in the
network_rulestable with metadata (actor, IP, user agent, expiry). - Generates a managed
pg_hba.confentry:# BEGIN AXIOMDB MANAGED RULE proj_a1b2 rule_xyz host sq_square_experience_main square_experience_main_rw 203.0.113.10/32 scram-sha-256 # END AXIOMDB MANAGED RULE - Generates a PgBouncer auth entry.
- Generates a UFW firewall rule.
- Reloads PostgreSQL and PgBouncer configurations.
- Records a
network.rule.createdaudit event.
6. Copy branch URLs
axm branches urls --name mainThe output is ready for .env:
DATABASE_URL="postgresql://square_experience_rw:***@db.squareexp.com:6432/sq_square_experience_main?sslmode=require"
DIRECT_URL="postgresql://square_experience_owner:***@db.squareexp.com:5432/sq_square_experience_main?sslmode=require"URL anatomy
| Segment | Runtime URL | Direct URL | Purpose |
|---|---|---|---|
| Host | db.squareexp.com | db.squareexp.com | Same hostname, different ports |
| Port | 6432 | 5432 | PgBouncer vs direct Postgres |
| User | square_experience_rw | square_experience_owner | Runtime vs migration role |
| Database | sq_square_experience_main | sq_square_experience_main | Same database |
| SSL | sslmode=require | sslmode=require | TLS mandatory on both |
Copy via console
- Navigate to your project.
- Click on the Branches tab.
- Click Connect on the
mainbranch. - The modal shows pre-formatted blocks for Prisma, Drizzle, Kysely, node-postgres, SQLAlchemy, Django, Laravel, Go pgx, and Rust SQLx.
- Click the copy button next to the framework you're using.
7. Run a migration
Add both URLs to your .env:
DATABASE_URL="postgresql://square_experience_rw:***@db.squareexp.com:6432/sq_square_experience_main?sslmode=require"
DIRECT_URL="postgresql://square_experience_owner:***@db.squareexp.com:5432/sq_square_experience_main?sslmode=require"Configure Prisma to use both:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}Run the migration:
npx prisma migrate dev --name initPrisma uses DIRECT_URL (port 5432, owner role) to:
- Create a shadow database for diffing.
- Apply migration SQL.
- Record migration state in
_prisma_migrations.
And uses DATABASE_URL (port 6432, runtime role) for:
- Application queries.
- Connection pooling through PgBouncer.
Why two URLs are required
Prisma Migrate needs direct Postgres access for:
- Shadow database creation — Prisma creates a temporary database to diff your schema against the current state. The runtime role intentionally cannot create databases.
- Advisory locks — Migrations use advisory locks to prevent concurrent schema changes. PgBouncer in transaction mode doesn't support advisory locks.
- Prepared statements — Some migration operations use prepared statements that PgBouncer may not handle correctly.
The runtime role (_rw) only has CONNECT and read/write privileges on the database. It cannot create databases, manage roles, or perform DDL operations. This is a security boundary — if your application's database credentials are compromised, the attacker cannot modify the schema.
If connection fails
Check the Network page first. Most local failures are blocked by allowlist rules, not by database provisioning. Verify your IP is allowlisted and the rule hasn't expired.
8. Verify the setup
After migration, verify everything is working:
# Check migration status
npx prisma migrate status
# Inspect the schema
npx prisma db pull
# Generate the Prisma client
npx prisma generateVerify from the console
- Navigate to your project in the console.
- Click on the Tables tab.
- You should see your migrated tables listed.
- Click on a table to inspect columns and browse rows.
Verify from the CLI
axm monitoring summaryThis shows database size, connection counts, and migration state for the active project.
9. Create a branch for feature work
Branches let you test schema changes without touching the main database:
axm branches create --name feature-auth --source main --lifespan 7dThis provisions:
- A new database:
sq_square_experience_main_br_feature-auth - Independent credentials (owner, runtime, readonly roles)
- Schema copied from the source branch
- Independent network grants
Fetch the branch URLs:
axm branches urls --name feature-authUpdate your .env with the branch URLs and run migrations against the branch:
npx prisma migrate dev --name add-auth-tablesWhen the feature is complete, merge the schema changes to main and delete the branch:
axm branches delete feature-authComplete quickstart checklist
□ npm install -g axiomdb-cli
□ axm login
□ axm projects create --name "My App" --app-key my_app --env main
□ axm projects use <project-id>
□ axm network allow --current
□ axm branches urls --name main
□ Add DATABASE_URL and DIRECT_URL to .env
□ Configure schema.prisma with both URLs
□ npx prisma migrate dev --name init
□ npx prisma generate
□ Start building your applicationAccount and Onboarding
Create your AxiomDB account through Square IdP, configure your organization, invite your team, and provision your first project.
Dashboard Tour
Navigate every console surface — projects, branches, network rules, tables, backups, monitoring, audit, and settings — with detailed explanations of what each one does.