Concepts
Security
Tenant isolation, authentication, signing, key custody, customer-side responsibilities.
Security
This page describes Tidenda's security posture at a level useful to an administrator, a procurement reviewer, or an integrator deciding how much to trust the platform. It covers what the platform protects, how, and where the integrator's responsibility starts. Cryptographic details and the verification recipe live in Signing and signatures.
Tenant isolation
Every document, every API key, every webhook, every workflow, every AI operation, and every audit record is scoped to a tenant. The platform enforces this scope at every read and write — there is no cross-tenant path through any public surface or any operator action.
- API keys identify a single tenant. The
Authorizationheader determines tenant identity; payload fields claiming a different tenant are ignored. - Operator sessions carry a tenant claim from the identity provider. The active tenant is visible in the application and an operator's documents are filtered to that tenant alone.
- Storage keys (object store, database rows, search indices) carry the tenant id and are queried with the tenant filter applied at every layer.
- Outbound webhooks fire only for events on the tenant that owns the webhook subscription. A webhook on tenant A never receives an event from tenant B.
A tenant administrator can delete the tenant's data through the admin interface; the action is destructive and requires multiple confirmation steps because there is no in-platform "undelete."
Authentication
Operators
Operators authenticate through an OpenID Connect identity provider (Keycloak in the reference deployment). The platform doesn't store operator passwords; the identity provider owns the credential lifecycle, password rotation, MFA, federation, and any organisation directory.
Sessions are HTTP-only, secure cookies. Refresh tokens are held server-side; the browser only sees a session cookie. Sign-out clears the local session and ends the upstream SSO session as well, so the next sign-in always shows the identity provider's login form.
Integrators
Integrators authenticate with per-tenant API keys issued by an organisation administrator. Keys are random 32-byte secrets, stored as salted hashes. The plaintext is shown to the administrator exactly once at creation; the platform cannot recover it. Lost keys must be reissued.
Each key carries a set of scopes. A key with documents:create
cannot read phrases; a key with phrases:read cannot create
documents. New endpoints declare their own scopes — existing keys
keep working with their existing scope set until an administrator
grants the new scope.
Authorisation
Two authorisation models, layered:
- Roles govern what an authenticated operator can do. Roles come from the identity provider as realm roles on the user. Workflow transitions list the roles allowed to take them; the platform checks role membership before the transition is applied.
- Tenant scope governs what an authenticated identity (operator
or API key) can see. Tenant scope is checked before authorisation
rules even run. A request for a document outside the active
tenant's scope returns
404 Not Foundrather than403 Forbiddenso the existence of the resource isn't leaked.
Transport security
All public endpoints require HTTPS. The reference deployment terminates TLS at the edge with automatic certificate provisioning and renewal. Plain HTTP is refused outright for non-localhost origins.
The application enforces:
Strict-Transport-Securitywith a one-year max-age andincludeSubDomains.- HTTPS-only cookies.
- TLS 1.2+ at the terminator. TLS 1.3 where the load balancer supports it.
Webhook delivery security
Outbound webhooks carry two layers of integrity:
- HMAC-SHA256 over the request body and the dispatch timestamp. Proves the request came from someone who holds the webhook's shared secret (the platform — or anyone with whom the secret has been shared). Use this to gate request acceptance.
- Ed25519 over the document snapshot bytes. Proves the snapshot content itself was produced by Tidenda and has not been modified in transit. Use this when forwarding content to a third party.
A receiver should verify the HMAC before reading the body. The platform never logs secrets and never exposes them through the API after creation; if a receiver believes a secret may have been compromised, the administrator's response is to delete the webhook and create a new one. There is no in-place secret rotation today.
See Receiving webhooks and Signing and signatures.
Signing-key custody
Snapshot-signing keys are Ed25519 and rotate on the administrator's schedule. The active private key lives in deployment secrets — never in source control, never in plaintext at rest in the database, never on operator hardware. Historical public keys stay in the public trust list so previously signed content keeps verifying.
The reference deployment uses environment-variable-mounted secrets; larger deployments can plug in a dedicated secret manager.
Data at rest
- Documents live in an object store. The reference deployment uses S3 with server-side encryption (AES-256) and bucket-policy isolation per tenant.
- Indices and relational data live in PostgreSQL with the storage volume encrypted at rest.
- Caches and event streams live in Redis. Caches are reconstructible from the source of truth; the event streams are short-lived and reconstructible from the persistent store.
- Secrets (API key hashes, webhook secrets, signing private keys) live in the same storage as the rest of the data but are either hashed (API keys, webhook secrets) or held in deployment secrets (signing private keys).
Audit log
The platform maintains an append-only audit log for actions an administrator might need to investigate: workflow transitions, API key creation and deletion, webhook creation, sign-in events, and tenant-level destructive actions. Each entry records the actor (an identified operator, an API key, or a named system component), the target, and a timestamp.
Workflow transitions are also materialised into a queryable shadow table so administrators can answer "who transitioned this document when" without loading every document individually. The document's own history record remains the source of truth; the shadow table trails it and is rebuildable from event replay.
Audit entries are tenant-scoped — a tenant administrator can review their own tenant's history but not anyone else's.
Customer-side responsibilities
Some things sit on the integrator's side and the platform cannot enforce them:
- API key storage. A leaked API key authorises the actions its scopes allow. Treat keys as secrets equivalent to a password: store them in a secret manager, rotate on suspicion of compromise, never commit them to source control.
- Webhook endpoint hardening. The platform delivers signed payloads; the receiver decides whether to accept them. Verifying the signature, terminating TLS correctly, and not logging payload contents from rejected requests are the receiver's responsibility.
- Downstream verification. If snapshot content is republished, the downstream consumers should verify the Ed25519 signature. Tidenda cannot enforce verification at the consumer end; making it easy is what we can offer (see Signing and signatures and the verifier samples).
Reporting a security issue
Please report suspected vulnerabilities privately. Contact the operator of the deployment you're using; for the Tidenda project itself, see the contact information on the project's home page.
Please do not disclose vulnerabilities through public issues or chat channels until the operator has had a reasonable opportunity to respond.
Related pages
- Receiving webhooks — HMAC verification, replay protection, deduplication.
- Signing and signatures — Ed25519 verification and key rotation.
- API overview — API key auth, scopes, rate limits.