{"revision":"9f11a31dd2951db0","language":"en","entry":{"id":"oidc-consent","kind":"endpoint","group":"oidc","title":"Sign in: the signed consent","method":"POST","path":"/oidc/requests/{id}/consent","paths":[],"summary":"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.","response":"{redirect, login, version, log}: the browser goes to redirect.","parameters":[{"name":"id","in":"path","required":true,"description":"The request id: 43 characters from the consent page's address (`?req=`) or its meta element."}],"sample":"/oidc/requests/{id}/consent","access":"private-code","base":"directory","notes":["time is Unix seconds within two minutes of the server. A request takes one consent; the same signature replayed answers 410."],"errors":["400 invalid_json","400 invalid_parameter","401 invalid_signature","401 stale_timestamp","403 key_banned","403 key_mismatch","403 veil_suspended","404 not_found","410 erased","410 request_expired","413 payload_too_large","422 invalid_consent","429 rate_limited","500 internal_error","503 busy","503 log_unavailable"],"related":["sign-in-with-veil"],"sections":[{"kind":"code","language":"shell","code":"curl -fsS --json @consent.json \"https://veil.rip/oidc/requests/$REQUEST_ID/consent\""}],"live":false,"responses":[{"status":200,"contentType":"application/json","description":"{redirect, login, version, log}: the browser goes to redirect.","fields":[{"name":"redirect","type":"string","description":"redirect_uri with code, state and iss."},{"name":"login","type":"integer","description":"The login's id (sid l<id> in the ID token)."},{"name":"version","type":"integer","description":"The card's version the login was checked against."},{"name":"log","type":"object","description":"{origin, index, size, root}: the version's entry and the verified checkpoint."}]}],"responseObjects":[],"errorFormat":"json","errorDetails":[{"status":400,"code":"invalid_json","description":"The body is not a JSON object, contains duplicate keys or has trailing data.","action":"Send one valid JSON object with `Content-Type` application/json.","scope":"endpoint"},{"status":400,"code":"invalid_parameter","description":"A path, query or body field is missing, malformed or outside its accepted range.","action":"Correct the field named in `error.message` before sending again.","scope":"endpoint"},{"status":401,"code":"invalid_signature","description":"The HTTP request signature does not verify.","action":"Sign the exact method, path and body bytes, without changing them afterwards.","scope":"endpoint"},{"status":401,"code":"stale_timestamp","description":"The signed timestamp is outside the accepted clock window.","action":"Compare the server Date header with your clock, then generate a fresh nonce, timestamp and signature.","scope":"endpoint"},{"status":403,"code":"key_banned","description":"The device signing key is suspended by Veil staff.","action":"Use an authorised active key or ask staff to review the restriction.","scope":"endpoint"},{"status":403,"code":"key_mismatch","description":"The signing key does not have authority over this card or operation.","action":"Use an active device key with the required owner or member role.","scope":"endpoint"},{"status":403,"code":"veil_suspended","description":"The card is suspended by the Veil staff, so it cannot sign in to apps.","action":"Nothing to retry while the suspension lasts.","scope":"endpoint"},{"status":404,"code":"not_found","description":"The requested card, key, alias, code or resource was not found.","action":"Check the identifier. Temporary codes and previews may already have expired or been used.","scope":"endpoint"},{"status":410,"code":"erased","description":"The card existed and was erased or removed. The response also carries its public erasure receipt.","action":"Stop using this card as current authority. Retain only the public receipt if needed.","scope":"endpoint"},{"status":410,"code":"request_expired","description":"The sign-in request was used or is older than 30 minutes.","action":"Go back to the app and start again.","scope":"endpoint"},{"status":413,"code":"payload_too_large","description":"The request body exceeds this endpoint’s byte limit.","action":"Reduce the encoded body. API-key management accepts at most 8 KiB.","scope":"endpoint"},{"status":422,"code":"invalid_consent","description":"The consent text is not the one this request needs: a field differs, is missing or is extra, or the JSON is not canonical.","action":"Build the text from GET /oidc/requests/{id} as it is, then sign it.","scope":"endpoint"},{"status":429,"code":"rate_limited","description":"An anonymous, signed-request or API-key allowance was exceeded.","action":"Wait at least `Retry-After` seconds. Share a queue and retry budget across your workers.","scope":"common"},{"status":500,"code":"internal_error","description":"An unexpected server error occurred. Internal details are not returned.","action":"Retry reads with bounded backoff. Check write results before sending a new signed operation.","scope":"common"},{"status":503,"code":"busy","description":"The application has reached a temporary concurrency or database limit.","action":"Wait `Retry-After` seconds and retry with bounded backoff.","scope":"common"},{"status":503,"code":"log_unavailable","description":"The public log cannot currently be read, verified or used for publication.","action":"For reads, keep the result unverified and try later. Before retrying a write, read the card to check whether publication completed.","scope":"endpoint"}],"responseHeaders":[{"name":"Content-Type","value":"application/json","description":"JSON, also for errors."},{"name":"Cache-Control","value":"no-store","description":"Private: never cached."}],"bodyFields":[{"name":"consent","in":"body","required":true,"description":"veil-rubrica:oidc-consent:v1, a newline, then canonical JSON {card, challenge, client, iss, key, nonce, redirect, request, scopes, state, time, v: 1}."},{"name":"signature","in":"body","required":true,"description":"The device key's signature of the exact UTF-8 bytes of consent (hex for Ed25519)."}],"documentationUrl":"https://veil.rip/docs/oidc-consent","supportsBrowserFetch":false,"browserMode":"local-or-server"}}