- Add Gitea Actions workflow; point README to gitea.d-bis.org/Sankofa_Phoenix/SMOA - Expand .gitignore for Spring H2 data, secrets, Kotlin .kotlin/, tooling - Track docs/api/generated ReDoc bundle; refresh api docs README - Android: network/auth/sync, UI shell, tests; backend credentials/integrity APIs - Docs, scripts (generate-api-docs), modules and core updates Made-with: Cursor
1.6 KiB
1.6 KiB
Tenant, API key, and unit header — threat model notes
What exists today
- API key (
SMOA_API_KEY/X-API-Key): shared-secret gate for/api/v1/*when configured. It does not identify a tenant or row-level security domain by itself. smoa.tenant.require-unit: when true, requests may requireX-Unit(or equivalent) so clients must declare a unit; the backend can filter read paths that honor the header (seeTenantFilter). This is not cryptographic proof of membership in that unit.- Multi-government payloads: optional
issuingAuthorityin credentialpayload_jsondocuments jurisdiction and org hierarchy for issuance audit; it does not enforce access control unless application logic is added.
Gaps (explicit)
- No binding between API key and allowed
unit/holderId/ tenant id in the database layer. - No row-level security (RLS) in PostgreSQL; all rows are visible to any authenticated client unless controllers add filters.
- Compromise of API key implies compromise of all data the backend stores until the key is rotated.
Hardening directions
- Issue per-device or per-tenant credentials (mTLS, JWT with
tenant_id/sub, or OAuth2 client credentials) instead of a single static API key where feasible. - Map principal → allowed units in policy service; enforce in every sync/pull handler.
- Enable PostgreSQL RLS or schema-per-tenant for strict isolation.
- Log and monitor
X-Request-Idand principal for sync audit (already partially covered bysync_audit_log).
See also docs/reference/GAPS-AND-INCONSISTENCIES.md and backend TenantFilter.