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 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.
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 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:
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
.sankofa.jsonin the project root (created bysankofa init, linked bysankofa login). HoldsprojectId,endpoint,environment— but never the Deploy Token.Global config
~/.sankofa/credentials.json(written bysankofa login). Holds the Deploy Token, endpoint, project ID, and the session used bysankofa 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
| 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> # written 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.
Where credentials and caches live
| Path | Contents |
|---|---|
~/.sankofa/credentials.json | Global 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>.ed25519 | Patch 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. |