API Authentication
CVD Portal provides two authentication methods for programmatic access: an OAuth 2.1 authorization server for autonomous agents and external applications, and static bearer API keys for direct scripts and CI/CD pipelines. Both methods enforce tenant isolation and role-based access control.
OAuth 2.1 Authorization Server
The platform operates a standards-compliant OAuth 2.1 authorization server. Agents obtain short-lived, scope-limited access tokens bound to an authenticated user and company.
Protocol characteristics
- Grant types:
authorization_codewith PKCE, andrefresh_token. - Mandatory PKCE: Proof Key for Code Exchange (RFC 7636) is mandatory for all clients. The
code_challenge_methodmust beS256. Theplainmethod is rejected. - Dynamic Client Registration: Clients can self-register using RFC 7591 at
/api/oauth/register. - Token rotation: Refresh tokens rotate on every use. Exchanging a refresh token issues a new access token and a new refresh token while revoking the previous one.
- Token storage: All tokens and authorization codes are stored hashed (SHA-256) at rest. Plaintext credentials are never saved in the database.
Endpoints
| Endpoint | Path | Protocol | Purpose |
|---|---|---|---|
| Authorization | /api/oauth/authorize | RFC 6749 / OAuth 2.1 | Authorization code request with PKCE S256 |
| Token | /api/oauth/token | RFC 6749 / OAuth 2.1 | Code exchange and refresh token rotation |
| Dynamic registration | /api/oauth/register | RFC 7591 | Client registration |
| Introspection | /api/oauth/introspect | RFC 7662 | Query token active status and metadata |
| Revocation | /api/oauth/revoke | RFC 7009 | Invalidate access and refresh tokens |
Discovery metadata
Clients can automatically discover endpoints and capabilities using standard metadata documents:
- Authorization Server Metadata (RFC 8414):
https://cvdportal.com/.well-known/oauth-authorization-server - Protected Resource Metadata (RFC 9728):
https://cvdportal.com/.well-known/oauth-protected-resource
Environment variables
The authorization server supports the following configuration options:
| Variable | Default | Description |
|---|---|---|
OAUTH_ACCESS_TOKEN_TTL_SECONDS | 3600 (1 hour) | Lifetime of issued access tokens in seconds |
OAUTH_REFRESH_TOKEN_TTL_SECONDS | 2592000 (30 days) | Lifetime of issued refresh tokens in seconds |
Scope Taxonomy & Enforcement
Every MCP tool and version 1 REST endpoint enforces a specific scope requirement.
Scopes
| Scope | Grants | Endpoints & Tools |
|---|---|---|
read | Read-only compliance data, submissions, products, and SBOMs | GET /v1/compliance/*, GET /v1/products, GET /v1/sbom, GET /v1/vulnerabilities/*, GET /v1/jobs/*, POST /v1/jobs (classification), get_compliance_status, generate_csaf_advisory, assess_response, get_next_deadline, get_next_task, get_job_status, submit_job, ask_expert, get_conformity_gaps |
submissions:write | Submit vulnerability reports | POST /v1/vulnerabilities, submit_vulnerability |
products:write | Create and update products | POST /v1/products |
sbom:write | Push SBOMs from CI/CD | POST /v1/sbom |
sarif:write | Push SARIF pipeline scan findings | POST /v1/scan/sarif |
webhooks:write | Register webhook callbacks | POST /v1/webhooks/register |
gdpr:export | Export company data archive | GET /v1/gdpr/export |
forge:submissions:read | Read submissions for Jira sync | GET /v1/forge/submissions |
article14:prepare | Prepare Article 14 notification dossiers | POST /v1/jobs, submit_job |
advisory:draft | Draft CSAF and OpenVEX advisories | POST /v1/jobs, submit_job |
conformity:prepare | Prepare conformity assessment & import prefill | POST /v1/jobs, submit_job |
Enforcement rules
- OAuth tokens: Strictly limited to the consented scopes. Access to an endpoint or tool outside granted scopes returns HTTP 403 with an RFC 6750 challenge header:
WWW-Authenticate: Bearer error="insufficient_scope", scope="<required>". - Legacy API keys: A legacy key with an empty scope list maintains unrestricted access for backward compatibility. A key with specified scopes enforces those scopes.
- Plan gates: Scope checks and plan tier gates operate independently. A caller must hold the required scope and the company subscription must permit the feature.
Human Approval Queue for Irreversible Actions
Autonomous agents can prepare drafts and assemble packages, but cannot execute binding or outward-facing actions directly.
Every irreversible action initiated by an agent enqueues a PendingApproval record in the company workspace:
- Article 14 stage filing: Marking early warnings or full notifications as filed on the ENISA Single Reporting Platform (SRP).
- Security advisory publication: Transitioning draft advisories to published status.
- Declaration of Conformity issuance: Issuing and signing the EU Declaration of Conformity (
ISSUE_DOC). Agents assemble draft declarations, but cannot issue them directly.
A company administrator reviews, approves, or rejects pending actions in the dashboard under Settings → Approval Queue (/settings/approvals). Approvals execute idempotently through the canonical execution path. Webhooks notify administrators when an approval request arrives (approval.requested).
Asynchronous Job Layer
Long operations execute through background jobs to prevent HTTP timeout failures.
Operations
The following operations run asynchronously through the job system:
- Product classification. Analyzes product description text against CRA Annex III and Annex IV categories (
CLASSIFY_PRODUCT). - Artifact drafting. Drafts CRA technical file artifacts using the assessment model chain (
DRAFT_ARTIFACT). - Import prefill. Extracts conformity model fields from product documentation with per-field provenance and confidence flags (
IMPORT_PREFILL). Fields with confidence below threshold are flagged for human review. - Server auto-enrichment. Closes enrichable gaps automatically using external vulnerability data, EPSS, KEV, and standards mappings (
AUTO_ENRICH). - Dossier assembly. Compiles the Annex VII technical documentation index and drafts the Annex V Declaration of Conformity (
ASSEMBLE_DOSSIER). Does not issue the declaration.
Endpoints and tools
| Interface | Method / Tool | Description |
|---|---|---|
| REST | POST /api/v1/jobs | Submit a new background job. Returns HTTP 202 with job ID. |
| REST | GET /api/v1/jobs/[id] | Query current job status, progress, and result. |
| REST | GET /api/v1/compliance/gaps | Query structured conformity gaps and missing evidence. |
| MCP | submit_job | Enqueue a new background job. |
| MCP | get_job_status | Query job status and result. |
| MCP | get_conformity_gaps | Query structured conformity gaps across requirements. |
| MCP | ask_expert | Consult the CRA regulatory expert assistant. |
Idempotency
Requests can include an idempotencyKey string. When a submit request carries an existing key for the company, the platform returns the existing job record without starting duplicate work.
Signed completion push
Callers can provide an optional callbackUrl and callbackSecret. When the worker finishes processing the job, the server sends an HTTP POST request to the callback URL.
The push notification includes the following headers:
X-CVD-Timestamp: Unix timestamp of the push event.X-CVD-Signature-256: Signature string in formatt=<timestamp>,v1=<hmac-sha256>.
The server validates all callback URLs against Server-Side Request Forgery rules before saving and before dispatch. The push delivery operates in non-blocking mode with exponential retry backoff.
Regulatory Expert Assistant (MCP ask_expert)
Autonomous agents can consult the CRA regulatory expert tool (ask_expert) to resolve compliance ambiguities during the conformity run.
- Scope:
read. - Advisory nature: The tool provides advisory guidance only. It never claims that a Declaration of Conformity or Article 14 filing has occurred.
- Grounded answers: Responses cite official European Union legal sources including Regulation (EU) 2024/2847 and applicable harmonized standards.
- Structured needs: When the expert requires missing product or architecture details to answer definitively, it returns a structured
needobject with the target field, rationale, and question for human clarification.
Legacy Bearer API Keys
Administrators can provision static API keys in the dashboard under Settings → API Keys.
API keys are intended for server-to-server workflows and CI/CD integrations. Each key carries an optional scope list and an optional IP allowlist. Keys are transmitted via the standard HTTP header:
Authorization: Bearer <your-api-key>
Keys are stored as SHA-256 hashes. In the event of compromise, an administrator can immediately revoke or rotate the key in the dashboard.