Why Offline Auth Matters
On-device AI models like Gemma 4 run locally — on phones, Raspberry Pis, laptops, and edge servers. These devices are frequently disconnected: airplane mode, poor cellular coverage, air-gapped environments, or simply cost-conscious users who limit data usage. Without offline authorization, agents on these devices face two bad options:- No auth at all — the agent runs unchecked while offline, then syncs results later with no accountability trail
- Block until online — the agent refuses to operate without connectivity, defeating the purpose of on-device inference
Architecture
Offline authorization operates in three phases:Phase 1: Provisioning
While the device has connectivity, the developer’s application callsPOST /v1/consent-bundles to create a consent bundle. This is a standard Grantex authorization flow — the end-user must have already consented to the requested scopes.
The bundle contains:
- Grant token (RS256 JWT) — the same token format used online
- JWKS snapshot — the server’s public keys at the time of issuance, used to verify the token signature offline
- Ed25519 audit key pair — used to sign offline audit entries so the server can verify they originated from this device
- Sync endpoint — the URL for uploading audit entries when reconnected
- Offline expiry — the point after which the bundle is no longer valid
Phase 2: Offline Operation
Every time the agent performs an action, the offline verifier:- Decodes the JWT header and resolves the signing key from the JWKS snapshot by
kid - Verifies the RS256 signature — blocks
noneandHS256algorithms - Checks
expwith configurable clock skew tolerance - Checks
iatis not in the future - Extracts Grantex claims (
agt,sub,scp,grnt,delegationDepth) - Enforces required scopes (configurable: throw or log)
- Enforces maximum delegation depth
Phase 3: Sync
When connectivity returns, the device uploads its audit entries viaPOST /v1/audit/offline-sync. The server:
- Verifies the hash chain — each entry’s
prevHashmust match the previous entry’shash - Verifies Ed25519 signatures using the public key stored when the bundle was created
- Checks whether the grant has been revoked since the device went offline
- Reconciles entries with the cloud audit log
revocation_status: 'revoked' and includes the revocation timestamp so the device can determine which actions were authorized and which occurred after revocation.
ConsentBundle Reference
See Consent Bundles for the complete type reference and lifecycle documentation.Security Model
Guarantees
| Property | Guarantee |
|---|---|
| Token authenticity | RS256 signature verified against JWKS snapshot. Forged tokens are rejected. |
| Scope enforcement | The verifier checks scp claims against required scopes before every action. |
| Audit integrity | Hash chain + Ed25519 signatures make tampering detectable at sync time. |
| Time-bounded | Bundles expire after a configurable TTL (default 72 hours). |
| Delegation control | maxDelegationDepth prevents unbounded sub-delegation chains. |
| Encryption at rest | Bundles are stored with AES-256-GCM encryption. |
Limitations
| Limitation | Explanation |
|---|---|
| No real-time revocation | If a grant is revoked while the device is offline, the device will not learn about it until sync. Actions between revocation and sync are logged but the agent continues operating. |
| JWKS key rotation | If the server rotates its signing keys while the device is offline, the JWKS snapshot becomes stale. The validUntil field on the snapshot helps detect this. |
| Clock drift | The verifier uses a clock-skew tolerance (default 30 seconds), but devices with significantly drifted clocks may incorrectly accept or reject tokens. |
| No online budget enforcement | Budget debits require a network call. Offline agents cannot enforce budgets in real time. |
| Bundle theft | If an attacker obtains both the encrypted bundle file and the encryption key, they can use the grant token until it expires. Use hardware-backed storage (Keychain, Secure Enclave) on supported platforms. |
Threat Model
The offline authorization system is designed to defend against:- Token forgery — RS256 signatures cannot be forged without the server’s private key
- Audit log tampering — breaking the hash chain or forging Ed25519 signatures is detectable at sync
- Scope escalation — the verifier enforces the scopes embedded in the token at issuance
- Replay attacks — each token has a unique
jtiand expiry; each audit entry has a monotonic sequence number
Sync Behavior
Batch Upload
Audit entries are uploaded in configurable batches (default 100 entries). Each batch is retried up to 3 times with exponential back-off (200ms, 400ms, 800ms). Failed batches are reported in theSyncResult.errors array but do not block subsequent batches.
Idempotency
Each entry has a monotonicseq number. The device tracks syncedUpTo in a local marker file. Re-syncing the same entries is safe — the server deduplicates by sequence number within a bundle.
Conflict Resolution
The server is the authority. If the server already has entries for a given bundle and sequence range, it compares hashes. Matching hashes are accepted; mismatched hashes are flagged as conflicts and included in the audit trail.Revocation While Offline
Grant revocation is a server-side operation. When a grant is revoked:- The device continues operating with the cached bundle until sync
- At sync time, the server returns
revocation_status: 'revoked'with the revocation timestamp - The device should stop using the bundle and delete the local copy
- Actions that occurred after the revocation timestamp are flagged in the audit log
offlineTTL values for sensitive operations. For example, a medical device agent might use 1h while a home automation agent could use 72h.
Audit Log Integrity
The offline audit log uses two complementary integrity mechanisms:Hash Chain
Each entry includes a SHA-256 hash computed from:prevHash field links to the previous entry’s hash, forming a chain. The first entry uses the sentinel value GENESIS_HASH (0000000000000000). Breaking any entry invalidates all subsequent hashes.
Ed25519 Signatures
Each entry’s hash is signed with the Ed25519 private key from the consent bundle. The server holds the corresponding public key and verifies signatures at sync time. This proves that entries were produced by the device that received the original bundle.Verification
UseverifyChain() to check the integrity of a log locally:
Next Steps
- Consent Bundles — full ConsentBundle reference and lifecycle
- Quickstart: Gemma 4 — hands-on tutorial
- Gemma 4 SDK Reference — complete API reference
- Consent Bundles API — REST API endpoints
- Offline Sync API — sync endpoint reference