Purpose
The Auth CLI exposes Firebase Authentication user administration through the same AuthListService used by the macOS app. It supports emulator projects by default and supports live Firebase projects when a bearer token is supplied.
All successful commands print JSON. Failures return exit code 1 with a readable error on stderr.
Project Setup
project connect --name Local --project-id demo-firestruct --environment emulator --host localhost --port 8080 --auth-port 9099
project select Local
Options shared by Auth commands:
--project <name|firebaseProjectID|uuid>overrides the selected project.--tenant <tenant-id>overrides the selected Auth tenant for one command.--project-authexplicitly uses project-level Auth for one command, bypassing a selected tenant.--authorization "Bearer <token>"supplies a live-project authorization header.--access-token <token>is shorthand for--authorization "Bearer <token>".
For emulator projects, Firestruct sends the emulator admin authorization header automatically.
Discover And Select Auth Tenants
auth tenants list
auth tenants list --page-size 100
auth tenants select clinic-a
auth tenants current
auth tenants select project-auth
auth tenants list discovers Firebase Auth tenants through Identity Toolkit and identifies the selected scope. Live projects require --access-token or --authorization. auth tenants select <tenant-id> stores a selection independently for each linked Firebase project; subsequent list, search, create, update, enable/disable, delete, import/export, transfer-source, and script commands use it automatically.
Use auth tenants select project-auth to clear the saved tenant. In automation, prefer explicit --tenant or --project-auth so a previous interactive selection cannot change the target scope.
List Users
auth list --limit 100
auth list --limit 100 --page-token <nextPageToken>
auth list --filter alice --sort-by email
auth list --sort-by createdAt --descending
Options:
--limitdefaults to1000and must be between1and1000.--page-tokenrequests a specific Firebase Auth page.--filterapplies a client-side substring filter across UID, email, phone, and display name.--sort-byacceptsuid,email,phoneNumber,createdAt, orlastLoginAt.--descendingreverses the sort order.
Output contains project, users, nextPageToken, and logs. Each user includes profile fields, disabled and email verification state, custom claims JSON, metadata timestamps, password hash/salt when returned by Firebase, linked provider IDs, and provider details.
Search And Get
auth search --uid auth_alice
auth search --email alice@example.test
auth search --phone +15555550123
auth get --uid auth_alice
auth search and auth get use the Identity Toolkit lookup endpoint. Provide one of --uid, --email, --phone, or --search.
Create User
auth create --uid auth_alice --email alice@example.test --password secret
auth create --email alice@example.test --display-name "Alice" --email-verified true
auth create --uid auth_alice --custom-claims '{"role":"admin"}'
Supported fields:
--uid--email--password--phone--display-name--photo-url--disabled true|false--email-verified true|false--custom-claims '<json object>'
Update User
auth update --uid auth_alice --display-name "Alice Updated"
auth update --uid auth_alice --disabled true
auth update --uid auth_alice --email-verified false
auth update --uid auth_alice --custom-claims '{"tier":"pro"}'
auth update --uid auth_alice --delete-password
--uid is required. The other fields match auth create. Custom claims are validated by the core Auth service before the request is sent.
Bulk Enable, Disable, And Delete
auth disable --uid auth_alice --confirm
auth enable --uids auth_alice,auth_bob --confirm
auth delete --uid auth_alice --confirm
auth delete --uids auth_alice,auth_bob --confirm
Bulk mutation commands require --confirm. --uid targets one user, and --uids accepts a comma-separated list.
Output includes a task object with queued/running/success lifecycle fields, processed and total operation counters, attempt count, duration, and any retained error description.
Export Users
auth export --format json --output build/auth-users.json
auth export --format csv --output build/auth-users.csv
auth export --search alice@example.test --output build/alice.json
auth export --uids auth_alice,auth_bob --fields uid,email,customClaims --output build/auth-users.json
Options:
--format json|csvdefaults tojson.--output <path>is required.--search <text>exports lookup results instead of all users.--uidor--uidsnarrows the exported all-user result.--page-sizecontrols all-user pagination and defaults to1000.--fields <comma-separated AuthExportField names>selects export fields.--no-metadataomits metadata fields.--no-custom-claimsomits custom claims.--include-hashesincludes password hash and salt when Firebase returns them.--delimiter <char>sets CSV delimiter.--json-structure array|keyedByUID|envelopecontrols JSON shape.--timestamps iso8601|unixMilliseconds|unixSecondscontrols timestamp encoding.
Output includes export counts, destination metadata, logs, and the completed task snapshot.
Import Users
auth import --file auth-users.json --format json --confirm
auth import --file auth-users.csv --format csv --uid-column uid --confirm
auth import --file auth-users.json --update-existing --confirm
Options:
--file <path>is required.--format json|csvdefaults tojson.--delimiter <char>sets CSV delimiter.--no-headertreats CSV as headerless.--uid-column <name>defaults touid.--update-existingupdates users when create returns an already-exists error.--confirmis required.
JSON imports accept either an array of user objects or an object keyed by UID. CSV imports require a UID column unless --no-header is used.
Output includes imported count, logs, and the completed task snapshot.
Transfer Users
auth transfer --target Staging --confirm
auth transfer --target Production --uids auth_alice,auth_bob --confirm
auth transfer --target Staging --delete-source --confirm
auth transfer --target Production --tenant source-tenant --target-tenant target-tenant --confirm
The selected or --project project is the source. --target accepts the target project name, Firebase project ID, or UUID. Transfer exports users from the source, creates or updates them in the target, and optionally deletes source users with --delete-source.
By default, --tenant is used for both source and target tenant scopes. Pass --target-tenant when the target Auth tenant differs.
When --tenant is omitted, the source uses that project's selected Auth tenant. The target defaults to the same scope unless --target-tenant is supplied.
For live-to-live or emulator-to-live transfer, use target-specific credentials when needed:
auth transfer --target Production --access-token <source-token> --target-access-token <target-token> --confirm
Output includes transferred count, optional source deletion count, logs, and the completed task snapshot.
JavaScript Auth Scripts
auth run --file scripts/auth-report.js
auth run --script 'async function run(ctx, admin) { const r = await admin.auth().listUsers(100); return r.users.map(u => ({ uid: u.uid, email: u.email })); }'
auth run loads all Auth users first, injects them into the local JavaScript runtime as admin.auth() data, and returns structured documents, raw runtime JSON, and logs. The Auth shim supports common Admin Auth methods such as listUsers, getUser, getUserByEmail, getUserByPhoneNumber, getUsers, createUser, updateUser, deleteUser, deleteUsers, setCustomUserClaims, token helpers, and email link helpers.
Options:
--file <path>reads a script from disk.--script <text>runs an inline script.--timeout <seconds>defaults to15.
Script mutations run against the local runtime snapshot, not Firebase. Use auth create, auth update, auth delete, auth import, or auth transfer for Firebase mutations.
Auth-To-Firestore Routes
Routes connect one exact Auth scope—project-level Auth or one tenant—to a Firestore project, database, collection, and UID mapping strategy. They are persisted in the same local project registry used by the macOS app.
Create a document-ID route:
auth tenants select clinic-a
auth routes set --firestore-project CustomerData --database customer-data --collection tenantUsers
Create a field-value route for a shared collection:
auth routes set \
--firestore-project CustomerData \
--database customer-data \
--collection users \
--key-strategy field-value \
--uid-field auth.uid \
--tenant-field tenantID \
--tenant-value clinic-a
Route management commands:
auth routes list
auth routes list --all
auth routes disable --id <route-uuid>
auth routes enable --id <route-uuid>
auth routes delete --id <route-uuid> --confirm
set creates a route unless --id <route-uuid> identifies an existing route to update. Collection paths must have an odd number of segments. The database must be configured on the target project. Field-value routes require --uid-field; --tenant-field and --tenant-value must be supplied together. Only one route may exist for each Auth project/tenant scope.
Resolve from Auth to Firestore:
auth routes resolve-auth --uid auth_alice
auth routes resolve-auth --uid auth_alice --plan-only
Resolve from a Firestore document back to Auth:
project select CustomerData
auth routes resolve-firestore --document users/profile-1 --auth-project AuthProject
auth routes resolve-firestore --document users/profile-1 --auth-project AuthProject --tenant clinic-a
Resolution restores the route's Firestore database and Auth tenant instead of relying on the currently selected database. Shared-collection routes apply their tenant discriminator. Ambiguous reverse matches fail until --auth-project, --tenant, or --project-auth identifies an exact Auth scope. --plan-only prints route/query resolution without Firebase calls when the mapping permits it; field-value reverse resolution must read the document to obtain the UID.
Firestore requests accept --firestore-access-token or --firestore-authorization; reverse Auth lookup accepts --auth-access-token or --auth-authorization. The unprefixed credential flags remain the fallback for both.
Run Through Selected Module
module select auth
run list --limit 100
run export --output build/auth-users.json
run dispatches Auth actions when the selected CLI module is auth.
Current CLI Gaps
The GUI Auth module still has a few workflows that are not first-class CLI commands:
- Direct Storage file-picker profile-photo upload proof; the covered GUI path is the selected Storage download URL handoff to
photoURL. - Saved Auth query/script presets.
- Durable retry/cancel across separate CLI invocations; completed Auth task snapshots are persisted through the shared Tasks CLI history.
Source Anchors
Sources/FirestructCLIKit/AuthCommand.swiftSources/FirestructCLIKit/AuthTenantsCommand.swiftSources/FirestructCLIKit/AuthRoutesCommand.swiftSources/FirestructCLIKit/FirestructCLI.swiftSources/FirestructCore/AuthFirestoreLinkRouteService.swiftSources/FirestructCore/AuthListService.swiftSources/FirestructCore/AuthListService+Operations.swiftTests/FirestructCLIIntegrationTests/FirestructCLIIntegrationTests.swift