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_…Dashboard JWTsession tokenLog 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.
sankofa loginIt prompts for the API endpoint (default https://api.sankofa.dev), opens a login page, and waits for the callback. On success it caches your credentials locally and, if the current directory is a Sankofa project, backfills the empty app_id / api_key fields in sankofa.yaml.
sankofa login --project # save to .sankofa.json in this project instead of global config
sankofa login --endpoint https://api.sankofa.devDeploy Token login (CI/CD)
For headless environments, authenticate directly with a pre-minted Deploy Token and a project ID — no browser round-trip.
sankofa login --deploy-token sk_deploy_xxxxxxxx --project-id proj_xxxxxxxxThe 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
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-authsankofa switch reuses your existing sign-in, so it can list your projects and switch without another browser trip.
Credential resolution order
Every authenticated command resolves credentials from the following sources, highest priority first:
Environment variables
SANKOFA_DEPLOY_TOKEN(deploy auth),SANKOFA_JWT(dashboard auth),SANKOFA_PROJECT_ID,SANKOFA_ENDPOINT,SANKOFA_ENVIRONMENT.SANKOFA_API_KEYis accepted as an alias forSANKOFA_DEPLOY_TOKEN.Project config
Per-project settings written by
sankofa init/sankofa login— project ID, endpoint, environment. Never holds a login token.Global login
Your saved account sign-in from
sankofa login.
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
| Variable | Purpose |
|---|---|
SANKOFA_DEPLOY_TOKEN | Deploy auth token for release / patch / status / preview / dist / submit. |
SANKOFA_JWT | Dashboard JWT for flags / config / catch / demo. |
SANKOFA_PROJECT_ID | Project ID (proj_…). |
SANKOFA_ENDPOINT | API base URL. Defaults to https://api.sankofa.dev. |
SANKOFA_ENVIRONMENT | live or test. Defaults to live. |
SANKOFA_ENGINE_VERSION | Override the Sankofa Flutter engine version the build resolves. |
SANKOFA_HOME | Override the cache root (default ~/.sankofa). Useful to isolate CI caches. |
SANKOFA_NO_UPDATE_CHECK | Set 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.
# 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> # paste the key printed by 'sankofa keys generate'app_idstringRequiredapi_keystringRequiredbase_urlstring?default https://api.sankofa.devengine_versionstring?signing_pubkeystring?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.
What's safe to commit — and what to protect
- Safe to commit:
.sankofa.jsonandsankofa.yamlcarry your project ID, endpoint, and the publishable runtime key (api_key, sent asx-api-key— a client-embedded key by design, like a Firebase or Stripe publishable key). Neither file holds a login token. - Never commit: your account login (created by
sankofa login) and your patch-signing private key (created bysankofa keys generate). Losing the signing key means you can't sign future patches; leaking it means someone else could — back it up somewhere safe and manage it withsankofa keys. - Engine binaries and other CLI state live under a local cache root you can relocate with
SANKOFA_HOME(handy for isolating CI caches). |~/.sankofa/flutter/<version>/| Bundled Sankofa Flutter SDK per engine version. |