Promotion and 4-Eyes Rule
The tk-ota-push promote command promotes an already approved and signed patch from an internal channel (such as staging or beta) to a higher channel (such as stable) without recompiling. This mechanism works hand-in-hand with the 4-eyes approval workflow (--staged / Maker-Checker).
1. The 4-Eyes Principle (--staged / Maker-Checker)
When publishing a sensitive patch, segregation of duties between the developer submitting the fix (Maker) and the security officer or release manager authorizing it (Checker) takes place in two steps:
- Initial Submission: Developer submits the patch to an internal channel (
staging) in quarantine (STAGED). - Four-Eyes Review: A distinct authorized reviewer (Release Manager or Security Officer) approves the patch.
- Digital Signature: The patch is signed with production cryptographic credentials.
- Production Availability: The patch becomes active and deployable on the
stablechannel.
Exact Server-Side Behavior (TkushPatch Server)
- Submission with
--staged: the CLI sendsauto_approve=false. The patch is saved with statusSTAGEDandhashSignature = null. WhileSTAGED, no mobile device can download it. - Tenant
enforceFourEyespolicy: even if the developer omits--staged(auto_approve=true), if the Tenant's governance policy enforces 4-eyes review (four-eyes policy == true), the server refuses auto-approval and forces the patch intoSTAGEDstatus. - Approval by a second actor: when calling
POST /api/admin/v1/patches/{patchId}/approve, ifapprovedByequalscreatedByandenforceFourEyesis enabled (or the Tenant has more than one member), the server rejects the request withHTTP 409 Conflict:Violation du Principe des 4 Yeux (Four-Eyes Principle) : L'approbateur (<email>) doit être différent du créateur du patch.
2. tk-ota-push promote Command
Once a patch has been validated on staging and has reached APPROVED_AND_SIGNED status, use promote to publish it to stable:
tk-ota-push promote --patch-id <uuid> [--to-channel stable] [options]
promote Options
| Option / Flag | Mandatory | Default | Description |
|---|---|---|---|
--patch-id | Yes | — | UUID of the source patch to promote |
--to-channel | No | stable | Destination channel (e.g., stable, beta) |
--tenant-id | No | shorebird.yaml / session / default | Tenant identifier |
--server | No | shorebird.yaml / env / http://localhost:8080 | OTA server URL |
--project | No | . | Flutter project path (to read shorebird.yaml) |
--json | No | false | Outputs raw JSON response |
3. Cryptographic Guarantees During Promotion
When tk-ota-push promote calls POST /api/admin/v1/patches/{patchId}/promote?target_channel=<channel>, the server performs the following checks (TkushPatch Server):
- Status verification: the source patch must be in
APPROVED_AND_SIGNEDstate. If it is stillSTAGEDorROLLED_BACK, the server returnsHTTP 409 Conflict:Seul un patch dans l'état APPROVED_AND_SIGNED peut être promu vers un autre canal (état actuel: STAGED) - Target channel verification: the destination channel must differ from the source channel, otherwise
HTTP 409 Conflictis returned:Le canal cible (staging) est identique au canal source du patch. - Binary immutability (Zero recompilation): the newly created patch on the target channel reuses the exact same differential artifact (
diffArtifactPath),targetSha256Hash, and symbols file (symbolsArtifactPath). - Independent sequential numbering: the server automatically computes the next sequential
patchNumberon the destination channel (findMaxPatchNumberForReleaseAndChannel + 1). - Per-channel signing engine re-signing: the server signs
targetSha256Hashusing the signing key bound to(tenantId, appId, targetChannel)and records provenance inapprovedByasPROMOTED_FROM_<SOURCE_CHANNEL>:<actor>.
Complete Workflow Example (staging to stable)
# Step 1: Publish to staging with 4-eyes quarantine
tk-ota-push patch 1.0.0+3 -p android --channel staging --staged -m "Fix SEPA transfer"
# (After a second administrator approves the patch in the Web Console)
# Step 2: Promote to the stable production channel
tk-ota-push promote \
--patch-id 8b73f831-29cf-4cb6-8801-44ebda29910a \
--to-channel stable
Terminal output:
Promotion du patch 8b73f831-29cf-4cb6-8801-44ebda29910a vers le canal 'stable'...
✅ Patch promu avec succès !
┌──────────────────────────────────────────────────────────────────────────
│ 🚀 REÇU DE PUBLICATION PATCH OTA #2
├──────────────────────────────────────────────────────────────────────────
│ ID Patch (UUID) : c19a4502-88ef-41a0-9123-77bcde112233
│ Application & Version: sara-money-demo • v1.0.0+3
│ Cible & Canal : android (aarch64) • Canal 'stable'
│ Statut & Rollout : APPROVED_AND_SIGNED (Déploiement : 100%)
...