Skip to main content

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_code with PKCE, and refresh_token.
  • Mandatory PKCE: Proof Key for Code Exchange (RFC 7636) is mandatory for all clients. The code_challenge_method must be S256. The plain method 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

EndpointPathProtocolPurpose
Authorization/api/oauth/authorizeRFC 6749 / OAuth 2.1Authorization code request with PKCE S256
Token/api/oauth/tokenRFC 6749 / OAuth 2.1Code exchange and refresh token rotation
Dynamic registration/api/oauth/registerRFC 7591Client registration
Introspection/api/oauth/introspectRFC 7662Query token active status and metadata
Revocation/api/oauth/revokeRFC 7009Invalidate 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:

VariableDefaultDescription
OAUTH_ACCESS_TOKEN_TTL_SECONDS3600 (1 hour)Lifetime of issued access tokens in seconds
OAUTH_REFRESH_TOKEN_TTL_SECONDS2592000 (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

ScopeGrantsEndpoints & Tools
readRead-only compliance data, submissions, products, and SBOMsGET /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:writeSubmit vulnerability reportsPOST /v1/vulnerabilities, submit_vulnerability
products:writeCreate and update productsPOST /v1/products
sbom:writePush SBOMs from CI/CDPOST /v1/sbom
sarif:writePush SARIF pipeline scan findingsPOST /v1/scan/sarif
webhooks:writeRegister webhook callbacksPOST /v1/webhooks/register
gdpr:exportExport company data archiveGET /v1/gdpr/export
forge:submissions:readRead submissions for Jira syncGET /v1/forge/submissions
article14:preparePrepare Article 14 notification dossiersPOST /v1/jobs, submit_job
advisory:draftDraft CSAF and OpenVEX advisoriesPOST /v1/jobs, submit_job
conformity:preparePrepare conformity assessment & import prefillPOST /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:

  1. Product classification. Analyzes product description text against CRA Annex III and Annex IV categories (CLASSIFY_PRODUCT).
  2. Artifact drafting. Drafts CRA technical file artifacts using the assessment model chain (DRAFT_ARTIFACT).
  3. 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.
  4. Server auto-enrichment. Closes enrichable gaps automatically using external vulnerability data, EPSS, KEV, and standards mappings (AUTO_ENRICH).
  5. 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

InterfaceMethod / ToolDescription
RESTPOST /api/v1/jobsSubmit a new background job. Returns HTTP 202 with job ID.
RESTGET /api/v1/jobs/[id]Query current job status, progress, and result.
RESTGET /api/v1/compliance/gapsQuery structured conformity gaps and missing evidence.
MCPsubmit_jobEnqueue a new background job.
MCPget_job_statusQuery job status and result.
MCPget_conformity_gapsQuery structured conformity gaps across requirements.
MCPask_expertConsult 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 format t=<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 need object 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.