Complete shorebird.yaml Reference
The shorebird.yaml file, placed at the root of your Flutter project and packaged into app assets (flutter_assets/shorebird.yaml), is parsed by two distinct components:
- The embedded Rust runtime engine (
updater/library/src/yaml.rsandconfig.rs) during mobile app boot. - The Dart deployment CLI (
FlutterProjectintk_ota_push/lib/src/cli/project.dart) duringrelease,patch,promote, andsymbolscommands.
The parser embedded within the Rust engine (YamlConfig::from_yaml in updater/library/src/yaml.rs) is a lightweight line-by-line key: value parser for top-level runtime keys (app_id, channel, base_url, auto_update, patch_public_key, patch_verification), and quietly ignores any nested or CLI-specific keys (tenant_id, web_console_url, flavors, environments, geo, rollout).
Comprehensive Supported Keys Table
| Key | Type | Consumer | Default | Required | Description |
|---|---|---|---|---|---|
app_id | String | Rust + CLI | Auto-detected by CLI | Yes (at Rust runtime) | Unique application identifier. If omitted in source YAML, FlutterProject.ensureShorebirdYamlAppId() injects it before compilation. |
base_url | String | Rust + CLI | https://api.shorebird.dev (Rust) / http://localhost:8080 (CLI) | Recommended | Base URL of the sovereign OTA server (without trailing slash). Rust queries {base_url}/api/v1/patches/check and {base_url}/api/v1/patches/events. |
channel | String | Rust + CLI | stable | No | Default distribution track (stable, staging, beta, or custom track). |
auto_update | bool | Rust | true | No | If true, the native C++/Rust engine triggers an automatic background update thread at each boot. If false, the Dart SDK TkOtaPush drives updates via Gatekeeper. |
patch_public_key | String | Rust + CLI | null | Yes (in strict mode) | Base64-encoded RSA public key (Base64) used by the Rust engine to verify cryptographic patch signatures. |
patch_verification | String | Rust | strict | No | Cryptographic signature validation strategy: strict or install_only. |
tenant_id | String | CLI | session.tenantId or default | No | Multi-tenant organization identifier submitted in administrative CLI requests. |
web_console_url | String | CLI | http://localhost:3000 | No | Web console URL opened by tk-ota-push login when the --web-url flag is omitted. |
environments | Map<String, String> | CLI | null | No | Dictionary mapping environment names (dev, staging, prod, uat) to target app_id values. Takes precedence over flavors. |
flavors | Map<String, String> | CLI | null | No | Dictionary mapping Flutter flavors (dev, staging, prod) to target app_id values. |
geo.default_countries | List<String> or String | CLI | null (Global) | No | Default ISO-2 country codes for phased geographical rollout (e.g., ["CI", "SN", "CM"] or "CI,SN,CM"). Aliases supported: geo.countries, rollout.default_countries, rollout.countries. |
Runtime Keys (Rust Engine)
app_id
Uniquely identifies the (app_id, channel, release_version) tuple during calls to POST /api/v1/patches/check.
- In the Rust engine:
app_id: ...is mandatory (missing required field: app_idotherwise). - In the
tk-ota-pushCLI: you do not have to hardcode it manually. If missing, the CLI resolves the identifier (via--app-id,--dart-define,environments,flavors, or native Gradle/Xcode inspection) and invokesensureShorebirdYamlAppId(effectiveAppId)to injectapp_id: "<effectiveAppId>"intoshorebird.yamlbefore running the Flutter build.
base_url
Base URL pointing to your self-hosted TkushPatch backend.
- Local development / emulator / LAN example:
http://192.168.0.199:8080 - Production example:
https://ota.bank.internal - The TkushPatch Server backend (
ShorebirdUpdaterController.resolveClientReachableUrl) automatically rewrites artifact download links ifbase_urlis behind a reverse proxy (X-Forwarded-Host/X-Forwarded-Proto).
auto_update
Accepts boolean true or false (invalid value for auto_update otherwise).
auto_update: false(Recommended withTkOtaPush): prevents the native C++/Rust engine from making automatic unconstrained network requests on startup. Decisions are delegated toTkOtaPush.instance.syncWithRemoteConfig(...)and the 3-stepRemoteConfigGatekeeper(0 wasteful network calls).auto_update: true: the native engine automatically pollsPOST /api/v1/patches/checkin the background on every launch, bypassing the Dart Gatekeeper.
patch_public_key
Base64-encoded RSA public key used to verify the hash_signature header returned by the server.
- When running
tk-ota-push releaseortk-ota-push patch,Publisher.prepare()automatically requestsGET /api/admin/v1/public-keyand updatespatch_public_key:inshorebird.yamlviaproject.writePublicKey(key). - If the server does not return a valid public key, the CLI halts the build immediately with a strict security
CliException.
patch_verification
Configures the cryptographic signature verification strategy in the Rust engine (PatchVerificationMode in updater/library/src/yaml.rs):
strict(Default): verifies the patch RSA signature both upon installation and at every application boot time, defending against flash storage tampering.install_only: verifies the RSA signature only during patch download and initial staging. Provides slightly faster cold boots but less protection against local post-installation tampering.- Any value other than
strictorinstall_onlyis rejected withinvalid value for patch_verification.
Advanced CLI Keys (tk-ota-push)
environments and flavors
When compiling multiple variants of your application, FlutterProject.appIdForEnvironment(env) checks environments first, then flavors, falling back to root app_id:
tenant_id: enterprise-banking
app_id: com.bank.mobile.prod
base_url: https://ota.bank.internal
channel: stable
auto_update: false
patch_verification: strict
environments:
dev: com.bank.mobile.dev
staging: com.bank.mobile.staging
prod: com.bank.mobile.prod
flavors:
dev: com.bank.mobile.dev
staging: com.bank.mobile.staging
prod: com.bank.mobile.prod
geo / rollout (Default Geographic Targeting)
FlutterProject.defaultCountries reads default ISO-2 country codes from geo.default_countries, geo.countries, rollout.default_countries, or rollout.countries:
geo:
default_countries:
- CM
- CI
- SN
Or compact inline syntax:
rollout:
countries: "CM,CI,SN"
Passing --countries to tk-ota-push patch (e.g., --countries "CI,SN" or --countries all) overrides this setting.
Typical shorebird.yaml Templates
Sovereign Production with Gatekeeper (Recommended)
tenant_id: sara-money
app_id: com.saramoney.retail
base_url: https://ota.saramoney.internal
web_console_url: https://console-ota.saramoney.internal
channel: stable
auto_update: false
patch_verification: strict
patch_public_key: MIIBCgKCAQEA...
Local Development / Standalone Demo
tenant_id: dev-lab
app_id: com.sample.app
base_url: http://192.168.0.199:8080
channel: stable
auto_update: true
patch_verification: strict
patch_public_key: MIIBCgKCAQEA...