veil

Sign in: the signed consent

The consent text signed by an active device key of a person's card. The server checks it against the card and its version in the verified log, keeps the login and gives the code.

POST/oidc/requests/{id}/consent
Access
Private code required
Client
Local or server client

Parameters#

NameLocationMeaning
idRequiredPathThe request id: 43 characters from the consent page's address (`?req=`) or its meta element.

JSON body#

NameLocationMeaning
consentRequiredJSONveil-rubrica:oidc-consent:v1, a newline, then canonical JSON {card, challenge, client, iss, key, nonce, redirect, request, scopes, state, time, v: 1}.
signatureRequiredJSONThe device key's signature of the exact UTF-8 bytes of consent (hex for Ed25519).

Request examples#

cURL
curl -fsS --json @consent.json "https://veil.rip/oidc/requests/$REQUEST_ID/consent"

Response#

HTTP 200application/json

{redirect, login, version, log}: the browser goes to redirect.

FieldTypeMeaning
redirectstringredirect_uri with code, state and iss.
loginintegerThe login's id (sid l<id> in the ID token).
versionintegerThe card's version the login was checked against.
logobject{origin, index, size, root}: the version's entry and the verified checkpoint.

Response headers#

HeaderValueMeaning
Content-Typeapplication/jsonJSON, also for errors.
Cache-Controlno-storePrivate: never cached.

Usage notes#

  • time is Unix seconds within two minutes of the server. A request takes one consent; the same signature replayed answers 410.

Errors#

API errors return an error object. Use error.code for program logic; error.message is English text for people and can change. Response and error guide

HTTPCodeMeaning and next step
400invalid_json

The body is not a JSON object, contains duplicate keys or has trailing data.

Send one valid JSON object with Content-Type application/json.

400invalid_parameter

A path, query or body field is missing, malformed or outside its accepted range.

Correct the field named in error.message before sending again.

401invalid_signature

The HTTP request signature does not verify.

Sign the exact method, path and body bytes, without changing them afterwards.

401stale_timestamp

The signed timestamp is outside the accepted clock window.

Compare the server Date header with your clock, then generate a fresh nonce, timestamp and signature.

403key_banned

The device signing key is suspended by Veil staff.

Use an authorised active key or ask staff to review the restriction.

403key_mismatch

The signing key does not have authority over this card or operation.

Use an active device key with the required owner or member role.

403veil_suspended

The card is suspended by the Veil staff, so it cannot sign in to apps.

Nothing to retry while the suspension lasts.

404not_found

The requested card, key, alias, code or resource was not found.

Check the identifier. Temporary codes and previews may already have expired or been used.

410erased

The card existed and was erased or removed. The response also carries its public erasure receipt.

Stop using this card as current authority. Retain only the public receipt if needed.

410request_expired

The sign-in request was used or is older than 30 minutes.

Go back to the app and start again.

413payload_too_large

The request body exceeds this endpoint’s byte limit.

Reduce the encoded body. API-key management accepts at most 8 KiB.

503log_unavailable

The public log cannot currently be read, verified or used for publication.

For reads, keep the result unverified and try later. Before retrying a write, read the card to check whether publication completed.

Shared request errors
HTTPCodeMeaning and next step
429rate_limited

An anonymous, signed-request or API-key allowance was exceeded.

Wait at least Retry-After seconds. Share a queue and retry budget across your workers.

500internal_error

An unexpected server error occurred. Internal details are not returned.

Retry reads with bounded backoff. Check write results before sending a new signed operation.

503busy

The application has reached a temporary concurrency or database limit.

Wait Retry-After seconds and retry with bounded backoff.