ROOSTby Axowl

Docs

HTTPS gateway API

A managed appliance checks Axowl caller authorization before requesting a quorum receipt.

Managed IRON3 document signing

Grant access to one key

In Axowl Role & Permission, grant org.roost_key.sign to the caller in the organization that owns the appliance. Limit the grant to the partition and key UUIDs. A Roost administrator or auditor needs a separate signing grant. The organization Owner follows the existing Axowl owner rule.

org.roost_key.sign:partitionid=<partition-uuid>,keyid=<key-uuid>

Select a document key with the IRON3 algorithm. Assign its partition to the intended appliance and wait for applied. For a one-use Request & Approval grant, send a fresh UUID in X-Approval-Invocation when requesting the authorization.

Sign a document

  1. Your application hashes the original bytes with SHA-256 and creates an ephemeral P-256 key pair. From its authenticated Axowl session, it sends the digest and public key to the authorization endpoint.
  2. Axowl returns a one-use authorization, device serial and policy revision. The application proves possession of its ephemeral private key and sends the proof, partition, key and digest to the named gateway within 60 seconds.
  3. The gateway checks its installed policy, authenticates itself to Axowl and redeems the authorization. Axowl checks current membership, signing rights, ownership, key version and policy again. Only then does the gateway ask the enrolled voters to seal the document.
POST /api/org/{slug}/roost/partitions/{partitionId}/keys/{keyId}/sign-authorizations
{"hash":"<64 lower-case hex digits>","callerPublicKey":"<base64url DER SPKI>"}

POST /v1/sign
Authorization: Roost <one-use authorization>
{"partitionId":"<uuid>","keyId":"<uuid>","hash":"<digest>","callerProof":"<proof>"}

Sign the following seven ASCII fields in order, with one LF between fields and no trailing LF. Encode UUIDs in lowercase with hyphens. Use ECDSA P-256/SHA-256, then base64url-encode the two 32-byte signature integers concatenated as r || s, without padding.

ROOST-SIGN-V1
<serial>
<partition UUID>
<key UUID>
<policy revision UUID>
<digest>
<authorization>

Save the returned verificationKeyId and signature with the digest. Supply these to POST /v1/verify as keyId, signature and data. A redeemed authorization records admission to the voters. A successful quorum receipt confirms the seal.

If a request is refused

Check the organization, effective role, key version and the selected appliance’s latest policy receipt. A copied authorization without the private proof, a different digest, or a second redemption is refused. Where a policy requires a separate per-signature quorum approval, this IRON3 route refuses the request. If the authority is unreachable, the gateway waits for a new request. After a timeout, reconcile any receipt before requesting another seal.

日本語

指定したパーティションの鍵で署名する

対象組織の Role & Permission で、利用者に org.roost_key.sign を付与し、partitionid と keyid を対象の UUID に限定します。管理者・監査者の役割だけでは署名できません。組織 Owner には Axowl 共通の権限規則が適用されます。

  1. 用途が document、方式が IRON3 の鍵を選び、パーティションを担当機器に割り当てます。機器の状態が applied になるまで待ちます。
  2. クライアントは文書の SHA-256 と一時 P-256 公開鍵を Axowl に送ります。回数制限付き承認には固有の X-Approval-Invocation が必要です。
  3. 発行から60秒以内に、一時秘密鍵による証明と許可を対象機器の /v1/sign に送ります。機器は投票前に Axowl で権限、鍵の版、ポリシーを再確認します。失効、改変、再利用、認証サーバーとの通信断は拒否されます。
  4. 検証には応答に含まれる verificationKeyId と署名、元のダイジェストを使用します。
한국어

지정한 파티션의 키로 서명하기

장치 소유 조직의 Role & Permission에서 호출자에게 org.roost_key.sign을 부여하고 파티션과 키 UUID로 범위를 제한합니다. 관리·감사 역할의 기본 권한에는 서명이 포함되지 않습니다. 조직 Owner는 기존 Axowl 권한 규칙을 따릅니다.

  1. 용도가 document이고 알고리즘이 IRON3인 키를 고릅니다. 파티션을 담당 상자에 배정하고 ‘적용됨’을 확인합니다.
  2. 로그인한 앱이 문서의 SHA-256과 요청용 임시 공개키를 Axowl에 보내 1회 허가를 받습니다. 횟수 제한 승인은 고유한 X-Approval-Invocation을 함께 보냅니다.
  3. 60초 안에 같은 요청을 임시 개인키로 증명해 상자에 보냅니다. 상자는 투표 전에 권한과 키 버전을 다시 확인합니다. 권한 회수, 해시 변경, 허가 재사용 또는 인증 서버 단절 시 서명을 거부합니다.
  4. 반환된 verificationKeyId와 서명, 원래 해시를 함께 보관해 검증에 사용합니다.

Local bench fixture

The short request below uses the explicit loopback demo flag. The managed gateway requires caller authorization.

POST /v1/sign (bench fixture)

{ "hash": "<SHA-256 hex digest>", "keyId": "release-ledger" }
{ "signature": "IRON3:<base64(kid1:ctr1:sig1|kid2:ctr2:sig2)>",
  "quorum": "2/3",
  "signers": [{ "kid": "...", "ctr": 42, "sig": "..." }],
  "missing": ["<kid>"] }

Fewer than two voters: 503 {"error":"QUORUM_NOT_MET","have":1,"need":2}.

POST /v1/verify

{ "data": "<the same SHA-256 hex digest>", "keyId": "release-ledger", "signature": "IRON3:..." }

Answers {"valid": true} when enough voters confirm. A receipt naming an unknown voter answers {"valid": false, "reason": "UNKNOWN_KID"}.

Hashing

The SDKs hash raw message bytes with SHA-256. If you call the API directly, send the digest. Passing the text of an existing digest to an SDK hashes it again.

Other endpoints

GET /v1/health and GET /v1/kill-switch report the proxy state.