Concept
Security model
Authentication, authorisation, row and column security, and credential protection in Kiwi Fabric.
Authentication#
Authentication is uniform across the three surfaces.
| Surface | Mechanisms |
|---|---|
| REST | Authorization: Bearer <api-key>, the X-Api-Key header, or Basic auth, enforced by middleware on all /api/* routes except first-time setup |
| PostgreSQL wire | SCRAM-SHA-256 challenge-response (RFC 5802) |
| Arrow Flight | Authorization: Bearer <api-key> or Authorization: Basic base64(userId:password) in gRPC metadata, enforced by a server-side interceptor |
Kerberos/SPNEGO sign-in is also available for Windows domain users.
API keys look like kwf_ followed by 32 random characters. Only a SHA-256 hash is stored; the raw key is shown once, at creation. Keys carry a name, creation time, optional expiry and last-used time, and can be revoked.
First-time setup. POST /api/auth/setup creates the first user and API key and fails with 409 if any user already exists.
No username enumeration. For an unknown user name, the PostgreSQL surface still sends a full dummy SCRAM challenge, so authentication fails at proof verification, not at user lookup. Response timing therefore does not reveal which user names exist.
Authorisation#
Users belong to groups. Groups and users are granted roles. Roles hold permissions with * wildcards on both the operation and the resource. Evaluation is deny-wins: an explicit deny anywhere in the chain overrides any allow.
On top of table-level permission, a role can carry:
- a row filter, a JSON predicate using the same grammar as saga filters, with
{"$user":"id"}and{"$user":"groups"}placeholders that resolve to the caller; and - column rules using one of four strategies: deny, mask to null, redact, or partially mask.
Enforcement happens before the in-process engine sees any fetched rows. That prevents a permitted aggregate from leaking data the user is not allowed to see, and it applies identically to REST, PostgreSQL wire, Arrow Flight and AI-generated queries.
Credentials at rest#
Data-source credentials are never stored in plaintext. The key-encryption backend is pluggable: a local machine-key store by default (with an explicit start-up warning), or Azure Key Vault, AWS Secrets Manager or GCP Secret Manager, selected by one configuration switch. See Credential storage.
Tenant isolation#
Each customer runs their own instance (silo model). There is no shared connection pool or execution context to misconfigure, which is the strongest structural protection against cross-tenant data leakage.