Skip to main content

Approvals and the Four-Eyes Principle (Maker-Checker)

The Approvals screen (/approvals, implemented in src/app/approvals/page.tsx) serves as the regulatory governance cockpit of TkushPatch. It implements the banking Maker-Checker (Four-Eyes Principle) separation of duties mandated by regulations including Normes de Gouvernance Bancaire, Sécurité Données Bancaires v4.0, and ISO 27001.

No OTA patch destined for the general public on the stable channel can be activated without passing this cryptographic validation gate.


1. Maker-Checker Principle and STAGED Quarantine​

When a mobile developer (ROLE_RELEASE_DEVELOPER) compiles and publishes a hotfix patch via the CLI (tk-ota-push patch) or the REST API, the patch instantly enters a state of technical quarantine:

Four-Eyes Approval Workflow (Maker-Checker)
  1. Patch Submission (Maker): Developer publishes a patch via CLI; it enters quarantine as STAGED.
  2. Peer Review (Checker): A separate authorized team member inspects patch details in the Web Console.
  3. Approval & Signing: Reviewer approves the patch, generating the production digital signature.
  4. Deployment: Status transitions to APPROVED_AND_SIGNED and rollout begins.

The STAGED Status​

  • The .vmcode binary is stored on the server, but the Data Plane API (/api/v1/patches/check) strictly refuses to serve it to general production clients.
  • Only testing devices whose client_id is explicitly whitelisted in the QA device table are permitted to download and execute quarantined patches.

2. The 3 Pre-Signing Guardrails​

Before enabling the final signature action, the Approvals screen automatically audits the artifact against three mandatory criteria:

GuardrailInspected AttributeFailure Outcome
1. Native Code LockingVerify no changes to native bridges or manifest definitions (patch.native_bridge_ok == true)Automatic Rejection: an OTA Dart patch cannot modify C++/Java/Obj-C code or manifest permissions without crashing the runtime.
2. Binary Archive IntegrityRecomputed SHA-256 checksum of the uncompressed micro-diff (targetSha256Hash)Red security alert: cryptographic signing is blocked to prevent disk corruption or man-in-the-middle tampering.
3. Dart Symbol ArchivingVerified existence of the .symbols debug archive matching this patch numberOperational warning: prevents deobfuscation blindspots when troubleshooting production crashes.

3. RBAC Matrix on /approvals​

Access to /approvals and cryptographic signature capabilities is strictly governed by the active RBAC role:

RoleAccess to /approvals"Approve & Sign" Button"Reject / Cancel" Button
ROLE_ADMIN✅ Yes✅ Yes (unless author in multi-member mode)✅ Yes
ROLE_SECURITY_OFFICER✅ Yes✅ Yes (Designated Checker)✅ Yes
ROLE_RELEASE_DEVELOPER❌ Hidden❌ Prohibited❌ Prohibited
ROLE_SRE_ADMIN❌ Hidden❌ Prohibited❌ Prohibited
ROLE_AUDITOR_READONLY✅ Read-only view❌ Strictly read-only❌ Strictly read-only

[!IMPORTANT] If a developer attempts to navigate directly to /approvals, the Next.js RoleGuard component intercepts the route and displays a least-privilege access restriction screen.


4. Solo Tenant Mode vs. Multi-Member Enterprise​

In real-world workflows, startups and self-serve evaluations often operate with a single administrator. To avoid operational deadlocks while preserving institutional security, TkushPatch supports two operational governance modes:

A. Solo Developer Mode (isSoloTenant == true)​

  • Automatically detected when the tenant membership count is totalMembers == 1.
  • The sole administrator is granted an explicit derogation to self-approve patches.
  • Every self-approved patch is tagged with a distinct audit entry (audit_action: PATCH_APPROVED_SOLO_OVERRIDE), guaranteeing complete retrospective accountability.

B. Regulated Enterprise Mode (enforceFourEyes == true or totalMembers > 1)​

  • Self-approval is cryptographically and logically barred.
  • If the logged-in administrator originally submitted the patch, the signature button is disabled with the warning: "Awaiting sign-off by a secondary authorized officer (CISO or Co-Admin)".

5. The signing engine Cryptographic Signing Workflow​

When the Security Officer clicks Approve and Sign with cryptographic signing engine:

  1. The web console dispatches a JWT-authenticated request: POST /api/admin/v1/patches/{id}/approve.
  2. The TkushPatch Server backend validates operator identity and verifies actor.id != patch.author_id.
  3. The server calls the ShorebirdRsasigning engineSignerAdapter:
    • The 64-character lowercase hexadecimal SHA-256 digest of the new binary (message.as_bytes()) is routed to signing engine's Transit Engine.
    • signing engine signs this digest using the isolated digital signature/4096 key dedicated to the environment.
    • The resulting digital signature digital signature is Base64-encoded and persisted alongside the patch record.
  4. The patch status transitions to APPROVED_AND_SIGNED.
  5. An immutable audit event is appended to the regulatory audit log with IP address, timestamp, and operator metadata.