Commerce

Prove a Drupal site by its challenge, or have a code emailed

POST
/v1/drupal/connect/verify

Signed with the site key: signature is the Ed25519 signature, in base64url, over the key-sorted canonical JSON of the body without signature.

For a reachable site, Decionis fetches https://<site>/.well-known/decionis-challenge over HTTPS with no redirects, a five-second budget and a 16 KB cap. The site answers a JSON object with protocol (decionis-drupal-connect/1), purpose (challenge), connect_id, site_url, challenge, and signature: the site key's signature over the rest, signed the same way. A match claims the challenge, once, and connects the site (200). A site that answers without a valid proof is refused (403 DRUPAL_CHALLENGE_FAILED) and is not offered a code.

For a site Decionis cannot reach, or that gives no answer at all, a 6-digit code is emailed to the billing address instead (202); finish with connect/code. Until a code sender is configured, that answers 503 DRUPAL_EMAIL_CODE_UNAVAILABLE.

Connecting binds the site to one Decionis organization for good, creating it the first time, and answers that organization's least-privilege key (role MEMBER, scopes decision:read and decision:write) exactly once: only its hash is kept. Proving a connected site again issues a new key and revokes the one it had. The site starts in Shadow.

The challenge is single-use. A second verify of a used challenge answers 409 DRUPAL_CHALLENGE_ALREADY_USED, and a connect that has connected, failed or sent a code answers 409 DRUPAL_CONNECT_NOT_PENDING: start a new one. When Decionis refuses to bind the site, the answer carries that status with UPSTREAM_UNAVAILABLE.

Request Body

application/json

protocol*string
purpose*string
connect_id*string
Formatuuid
signature*DrupalSiteSignature

The site key's Ed25519 signature, base64url without padding, over the key-sorted canonical JSON of the body without signature.

Match^[A-Za-z0-9_-]{86}$

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/drupal/connect/verify" \  -H "Content-Type: application/json" \  -d '{    "protocol": "decionis-drupal-connect/1",    "purpose": "verify",    "connect_id": "a1b4c748-916a-48f3-ac78-f681f542c9c8",    "signature": "string"  }'
{  "status": "connected",  "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",  "api_key": "string",  "mode": "shadow",  "entitlement": null}