Skip to main content
Security

Credentials, logs and the things we deliberately do not keep.

Data residency answers where. This page answers what — what is stored, for how long, who can see it, and what happens when a key goes astray.

Security controls

Keys are hashed, never stored

An API key is shown to you exactly once, at the moment it is created. What we persist is a SHA-256 hash of the key plus a short display prefix for identification. If you lose a key we cannot recover it — we can only revoke it and issue another. That is the correct trade-off, and any provider who can email you your key back has made the wrong one.

TLS in transit, everywhere

The API accepts TLS 1.2 and above only, with HSTS enabled. The onward connection from the gateway to AWS Bedrock is TLS-protected and authenticated with SigV4. Plain HTTP requests are redirected, never served.

No prompt logging by default

Request and response bodies are not written to disk. We record metadata for metering and diagnostics — timestamp, key, model, residency tier, regions, status, latency and token counts — and detected PII is recorded as types and counts only, never as values.

Debug capture is opt-in and expires

When you genuinely need to see a body to debug something, you can enable capture for a single key. It is off by default, it must be turned on deliberately, it is written to the audit trail, and it expires automatically after at most 24 hours. There is no way to leave it on indefinitely by accident.

IP allow-listing per key

Bind a key to specific source addresses or CIDR ranges. A key that leaks into a public repository is then useless to anyone outside your network. Allow-lists are evaluated before the request reaches the upstream, so a blocked request never consumes allowance.

Audit trail

Key creation, rotation, revocation, residency and privacy-mode changes, allow-list edits and debug-capture toggles are all recorded with the acting user, the source address and a timestamp. The trail is append-only from the application's point of view.

API keys

Shown once, hashed forever

Keys carry an issuer prefix so that a secret scanner, a log aggregator or a code reviewer can recognise one on sight and act before it is abused.

dj_live_7Qx4mA2vRkP9dLbT1yWnZsHf3jCgEu6V

└┬┘ └─┬┘ └───────────────┬──────────────────┘
 │    │                  │
 │    │                  └─ 32 characters of CSPRNG output
 │    └──────────────────── environment: live | test
 └───────────────────────── issuer prefix, so a leaked key is
                            identifiable in a log or a repo scan

Storage

We store a SHA-256 hash of the key and a display prefix such as dj_live_7Qx4…. Authentication is a constant-time comparison against the hash. The plaintext key exists in our systems for the length of one HTTP response and is never written anywhere.

Rotation

Create the replacement key first, deploy it, then revoke the old one — there is no forced window in which both are invalid. Keys can also be given an expiry date so that a contractor's credential dies on schedule without anyone having to remember.

Compromise

Revocation is immediate and applies to in-flight requests as well as new ones. If you think a key has leaked, revoke it from the dashboard first and email support@dijitul.uk second.

Both header styles accepted

Authorization: Bearer and x-api-key both work, so an existing Anthropic integration authenticates without modification. Authentication reference →

Logging

Exactly what a request log row contains

Below is a representative row. Note the two null fields at the bottom: those are the prompt and the completion, and in normal operation they stay null.

request_logs row json
{
  "id": "01JBQ7X4M2N8P0R5T7V9W1Y3Z5",
  "api_key_id": 42,
  "occurred_at": "2026-07-30T09:14:02Z",
  "model": "claude-sonnet-4-6",
  "residency": "uk",
  "regions": ["eu-west-2"],
  "status": 200,
  "latency_ms": 2841,
  "input_tokens": 1204,
  "output_tokens": 388,
  "cache_read_tokens": 0,
  "privacy_mode": "tokenise",
  "pii_detected": { "EMAIL": 1, "NHS_NUMBER": 1 },
  "request_body": null,
  "response_body": null
}

Retention

Metadata rows are retained for 90 days and then deleted. Aggregated daily usage totals are kept for as long as we are required to keep billing records.

PII detections are counts, not values

The detector records that one email address and one NHS number were found. It does not record which ones. Storing the values would recreate exactly the exposure the feature exists to prevent.

Access control

Narrow the blast radius of a single key

Every key carries its own residency tier, privacy mode, allow-list and expiry. A key issued to a supplier need not be as powerful as the one your own production service uses.

Configuration is per key rather than per account, so the same tenant can run a locked-down UK-tier key for client matter alongside a permissive EEA-tier key for internal experimentation. Neither can be widened without an entry appearing in the audit trail.

  • Residency tier — a ceiling on where inference may run, enforced fail-closed.
  • Privacy mode — off, flag, redact or tokenise, applied before the request leaves the gateway.
  • Allowed IPs — individual addresses or CIDR ranges, checked before any upstream call.
  • Model allow-list — restrict a key to named models regardless of what the plan permits.
  • Expiry — an absolute date after which the key stops working with no further action.
key configuration json
{
  "name": "matter-summariser (production)",
  "residency": "uk",
  "privacy_mode": "tokenise",
  "allowed_ips": ["203.0.113.24/32", "198.51.100.0/28"],
  "expires_at": "2027-01-31T00:00:00Z"
}

Operations

Our posture, stated plainly

Including the parts that are still in progress. A security page that lists only finished work is not telling you very much.

Infrastructure

in place

The gateway, its database and its metering store run in the United Kingdom. Administrative access requires multi-factor authentication and is limited to named staff.

Secrets

in place

AWS credentials and third-party secrets are stored encrypted at rest and are not present in the application repository or in configuration files under version control.

Vulnerability management

to confirm

Dependencies are monitored and patched on a defined cadence. TODO(security): publish the patch SLA and the current dependency-scanning tooling before launch.

Independent testing

to confirm

TODO(security): commission and publish the date and scope of an independent penetration test. We will not claim one before it has happened.

Incident response

to confirm

TODO(legal): confirm the notification window for a personal data breach affecting a customer, consistent with the DPA and UK GDPR Article 33 obligations.

Certifications

stated honestly

We hold no security certification of our own today, and we do not borrow AWS's. See the residency page for what AWS certification does and does not cover.

Reporting a vulnerability

Email support@dijitul.uk with the subject line SECURITY. We will acknowledge within one working day. Please give us a reasonable window to remediate before disclosing publicly, and please do not test against another customer's tenant. TODO(security): replace with a dedicated security@ address and a published disclosure policy before launch.

Read the residency page next.

It sets out where inference happens, which certifications apply to the underlying platform, and what we explicitly will not claim.

Questions about a specific compliance requirement? support@dijitul.uk