CLI

Configuration & authentication

How the CLI authenticates — Deploy Tokens vs. dashboard JWTs, browser and CI login, the sankofa.yaml project file, environment variables, and credential resolution order.

The CLI needs two things before it can publish: who you are (authentication) and which project + environment you are shipping to. This page covers both, plus the sankofa.yaml file that Flutter Deploy reads at runtime.

Two credential types

Sankofa uses two different tokens for two different classes of command. Using the wrong one is the single most common auth error.

Deploy Tokensk_deploy_…
Publishing credential. Used by release, patch, deploy, status, preview, dist, submit. Scoped to one project. Mint one from the dashboard's Deploy tokens panel, or let sankofa login create one for you.
Dashboard JWTsession token
Full user session with project-role RBAC. Used by flags, config, catch, and demo — commands that read and write dashboard resources, not just deploy artifacts.

Log in

Browser login (interactive)

The default flow opens your browser, authenticates against your Sankofa account, lets you pick an organization + project, and mints a local Deploy Token bound to that project.

bash
sankofa login

It prompts for the API endpoint (default https://api.sankofa.dev), opens a login page, and waits for the callback. On success it saves credentials to ~/.sankofa/credentials.json and, if the current directory is a Sankofa project, backfills the empty app_id / api_key fields in sankofa.yaml and links .sankofa.json.

bash
sankofa login --project    # save to .sankofa.json in this project instead of global config
sankofa login --endpoint https://api.sankofa.dev

Deploy Token login (CI/CD)

For headless environments, authenticate directly with a pre-minted Deploy Token and a project ID — no browser round-trip.

bash
sankofa login --deploy-token sk_deploy_xxxxxxxx --project-id proj_xxxxxxxx

The token must start with sk_deploy_. The project ID can also come from the SANKOFA_PROJECT_ID environment variable. The CLI validates the token against the deploy API and records whether it belongs to the live or test environment.

Log out and switch projects

bash
sankofa logout             # clear both project + global scopes
sankofa logout --project   # clear the project-scoped credentials only
sankofa switch             # change the active project / environment without re-auth

sankofa switch reuses the long-lived session captured at browser login, so it can list your projects and mint a new Deploy Token without another browser trip.

Credential resolution order

Every authenticated command resolves credentials from the following sources, highest priority first:

  1. Environment variables

    SANKOFA_DEPLOY_TOKEN (deploy auth), SANKOFA_JWT (dashboard auth), SANKOFA_PROJECT_ID, SANKOFA_ENDPOINT, SANKOFA_ENVIRONMENT. SANKOFA_API_KEY is accepted as an alias for SANKOFA_DEPLOY_TOKEN.

  2. Project config

    .sankofa.json in the project root (created by sankofa init, linked by sankofa login). Holds projectId, endpoint, environment — but never the Deploy Token.

  3. Global config

    ~/.sankofa/credentials.json (written by sankofa login). Holds the Deploy Token, endpoint, project ID, and the session used by sankofa switch.

If nothing resolves, the command exits with a prompt to run sankofa login. The endpoint defaults to https://api.sankofa.dev and the environment defaults to live when unset.

Environment variables

VariablePurpose
SANKOFA_DEPLOY_TOKENDeploy auth token for release / patch / status / preview / dist / submit.
SANKOFA_JWTDashboard JWT for flags / config / catch / demo.
SANKOFA_PROJECT_IDProject ID (proj_…).
SANKOFA_ENDPOINTAPI base URL. Defaults to https://api.sankofa.dev.
SANKOFA_ENVIRONMENTlive or test. Defaults to live.
SANKOFA_ENGINE_VERSIONOverride the Sankofa Flutter engine version the build resolves.
SANKOFA_HOMEOverride the cache root (default ~/.sankofa). Useful to isolate CI caches.
SANKOFA_NO_UPDATE_CHECKSet to 1 to silence post-command update notices.

The sankofa.yaml project file (Flutter)

Flutter Deploy projects carry a sankofa.yaml at the project root. It is bundled as a Flutter asset and read at runtime by the SDK, so the app knows which project it belongs to and which server to talk to. sankofa init --deploy creates it; sankofa login fills the identity fields.

YAML
# sankofa.yaml — read at runtime from the asset bundle.
app_id: proj_xxxxxxxx        # your Sankofa project ID
api_key: sk_live_xxxxxxxx    # publishable runtime key (sent as x-api-key by the app)
# base_url: https://api.sankofa.dev   # only when self-hosting a non-default endpoint
engine_version: 3.44.1+sankofa-2      # written by 'sankofa engine install' / 'upgrade'
# signing_pubkey: <base64>            # written by 'sankofa keys generate'
app_idstringRequired
Your Sankofa project ID (proj_…). sankofa login fills this from the project you select.
api_keystringRequired
The project's publishable runtime key (sk_live_… or sk_test_…). The app sends it to the API as the x-api-key header. It is a client-embedded key by design, like a Firebase or Stripe publishable key.
base_urlstring?default https://api.sankofa.dev
Only written when your endpoint differs from the default (self-hosted / regional). Omitted for the standard cloud.
engine_versionstring?
The pinned Sankofa Flutter engine version (e.g. 3.44.1+sankofa-2). Written by sankofa engine install and re-written by sankofa engine upgrade.
signing_pubkeystring?
The base64 Ed25519 public key patches are signed with. Written by sankofa keys generate. The SDK verifies every patch against it before applying.

The engine pin is also mirrored to .sankofa/flutter-version. sankofa release, sankofa patch, and sankofa preview read the pin automatically, so every build uses the engine your project is locked to.

Where credentials and caches live

PathContents
~/.sankofa/credentials.jsonGlobal Deploy Token, endpoint, project ID, session.
.sankofa.json (project root)Project ID, endpoint, environment, installed products. Safe to commit — no token.
sankofa.yaml (Flutter project root)Runtime app_id + api_key + engine pin. Bundled into the app.
~/.config/sankofa/keys/<projectId>.ed25519Patch signing private key (0600). Back this up; never commit it.
~/.sankofa/engines/Cached Sankofa Flutter engine binaries.
~/.sankofa/flutter/<version>/Bundled Sankofa Flutter SDK per engine version.

Next steps

Edit this page on GitHub