API Authentication
VeriProof uses a compound API key model for ingest authentication. A compound key encodes the customer identity and a per-application secret in a single opaque string that the SDK handles automatically.
How authentication works
All HTTP functions in the VeriProof Ingest API use AuthorizationLevel.Anonymous on the Azure Function trigger. Authentication is enforced entirely in application-layer middleware — ApiKeyMiddleware — that runs before any function handler executes.
SDK request
│
│ X-API-Key: {secondary-segment}
▼
ApiKeyMiddleware
1. Extract X-API-Key header → 401 if missing
2. SHA-256 hash the secondary value
3. Query customer_keys table:
WHERE key_hash = $hash
AND is_active = TRUE
→ 401 if not found or inactive
4. Set resolved Customer ID in request context
│
▼
Function handler reads Customer ID from HttpContext
(never calls AuthenticateAsync directly)This architecture means:
- There is exactly one place where authentication happens (the middleware).
- Function handlers never need to re-check authentication.
- Rotating or revoking a key requires only a database update — no code change.
The compound key format
vp_cust_{customer-slug}.{azure-component}.{secondary-token}
│ │ │ │
│ │ │ └─ Per-key secret (32 bytes, base64)
│ │ └─ Azure Function infrastructure component
│ └─ Your customer account slug
└─ Prefix: always vp_cust_Example (illustrative — not a real key):
vp_cust_acme.akv7f4a2b3c9x.3xQr9pLm8N2vT4wKThe three segments explained
| Segment | What it is | Where it’s used |
|---|---|---|
vp_cust_{slug} | Fixed prefix + customer slug | Visual recognition in logs and code review |
{azure-component} | 32-char random secret, encrypted at rest in Key Vault | Azure infrastructure gate (when active); the Key Vault reference |
{secondary} | 32-byte random secret; SHA-256 hash stored in database | Application-layer authentication via X-API-Key header |
The SDK automatically splits the compound key on . boundaries and routes each segment to the correct header. If you are calling the REST API directly without the SDK, only the X-API-Key header (containing the secondary segment) is required.
The full compound key is shown only once at issuance. VeriProof stores only the SHA-256 hash of the secondary segment — the plaintext is never retrievable after generation. Store the key in a secret manager immediately after generating it.
Key hierarchy
VeriProof uses a two-level key hierarchy per customer account:
Customer Account
│
├── CustomerTenantKey (master, Staff-managed)
│ • One per customer
│ • Controls the azure-component used in all secondary keys
│ • Rotated by VeriProof staff; 7-day grace period for old value
│
└── CustomerKey (secondary, self-service)
• N per customer — one per application, team member, or environment
• Created and revoked by CustomerAdmin in the portal
• Each has its own secret and can be independently rotatedRevoking a CustomerKey does not affect other keys for the same customer. Rotating the CustomerTenantKey (azure-component) initiates a 7-day grace period during which both old and new values are accepted — giving you time to update deployed applications without downtime.
Key scopes
Each CustomerKey has a scope set at creation time:
| Scope | Access |
|---|---|
ingest:write | Submit compliance records to the Ingest API |
ingest:read | Query records via the Ingest API (enterprise read-back) |
sandbox | All above, restricted to the sandbox data partition |
A key’s scope cannot be widened after issuance. To grant broader access, issue a new key with the required scope.
Sandbox keys
Sandbox-scoped keys automatically route sessions to the sandbox data partition. The SDK sets an additional X-Veriproof-Sandbox: true header for sandbox keys — the ingest middleware checks this header to enforce the sandbox partition boundary.
The sandbox partition is completely isolated from production data at the database row-level security (RLS) layer, separate from key-scope checks. Even if a sandbox key somehow reached the production endpoint, RLS would prevent cross-partition writes.
Rate limiting and DDoS protection
ApiKeyMiddleware enforces per-key rate limits after authentication. Rate limits are configured per customer plan. Exceeding the limit returns 429 Too Many Requests with a Retry-After header indicating when the next window opens.
At the network layer, Azure DDoS Standard protects the Azure Function App infrastructure before requests reach application-layer middleware.
Generating and managing keys
Generate a key (Customer Portal)
- Open Settings, then select Account → Security.
- In Customer Keys, click Request New Key.
- Complete the request with the required name, scope, and environment.
- Copy the full compound key when the request is executed — it is displayed once.
Revoke a key
- Open Settings → Account → Security.
- In Customer Keys, submit a revoke request for the key.
- Revocation takes effect once the request is executed.
Rotate a key (zero downtime)
- Generate a new key with the same scope.
- Update your application’s secret configuration.
- Deploy the updated configuration.
- Verify new traces arrive in the portal.
- Submit a revoke request for the old key.
Storing keys securely
Keys should be stored in your platform’s secret manager — never committed to source control or logged to application output.
from veriproof_sdk import VeriproofClientOptions, configure_veriproof
from azure.keyvault.secrets import SecretClient
# Rotate keys without restarting — callable is invoked per export
def get_api_key() -> str:
return secret_client.get_secret("veriproof-api-key").value
configure_veriproof(
VeriproofClientOptions(
api_key_provider=get_api_key,
application_id="loan-review",
),
service_name="loan-review",
set_global=True,
)FAQ
Does VeriProof store my raw API key?
No. Only the SHA-256 hash of the secondary segment is stored. The raw key value is shown once at issuance and is not retrievable afterward.
What happens if my key is compromised?
Revoke it immediately from Settings → Account → Security in the Customer Keys panel and generate a replacement. Once the revoke request is executed, any request using the old key will receive 401 Unauthorized.
Can I tell which key was used for a given session?
Yes. The key_name of the key used to authenticate a session is recorded in the session’s audit metadata. You can filter the Decisions explorer by key name.
Do service-to-service calls within the portal use API keys?
No. The Customer Portal web application authenticates using JWT session tokens managed by the portal’s backend. API keys are exclusively for SDK-to-Ingest API communication.
Next steps
- Key Rotation & Revocation — detailed rotation procedures
- Multi-Tenant Isolation — how tenant boundaries are enforced after authentication
- Environments & API Keys — sandbox vs. production, key format reference