Seals
Concept: Seals & integrity.
Personal seal — /api/v1/seals (authenticated)
Section titled “Personal seal — /api/v1/seals (authenticated)”| Method · Route | Purpose | Source |
|---|---|---|
POST / | Register a seal. OwnerId is always the authenticated user (client input ignored); OwnerType = User or Organization, with a security Tier. | SealEndpoints.cs:28 |
DELETE /{credentialId} | Revoke a seal (by owner + ownerType). | :65 |
POST /check | Pre-flight: a personal seal needs only email + first passkey (Owner default policy; KYC gating is org-level). | :211 |
Seal registry — GET /api/org/{slug}/seals
Section titled “Seal registry — GET /api/org/{slug}/seals”Returns the org’s seals (:90):
- Master seal — one row if
Organization.OrgSealKeyIdis set ("{org} Master Seal", scopeALL (ROOT)). - Personal seals — each active member’s
UserCredential(s) surfaced as personal seals (one row per passkey; the first is the semantic personal seal).
Bind personal → master (sole proprietorship)
Section titled “Bind personal → master (sole proprietorship)”POST /api/org/{slug}/master-seal/bind-personal (:164) — for an independent sole proprietorship whose Owner had no passkey at org-creation time. After the Owner registers a passkey, this binds their first UserCredential as the org master seal. Owner-only; rejected if a master seal is already set (seals are immutable).
Registering a personal seal (passkey)
Section titled “Registering a personal seal (passkey)”RegisterPersonalSealModal drives the member’s cryptographic personal-seal ritual: platform-authenticator check → KYC pre-flight (/api/v1/seals/check, skipped for device-only enrollment) → api/passkey/add/options → navigator.credentials.get → api/passkey/add → POST /api/v1/seals (RegisterSealCommandHandler). The first passkey is the semantic Personal Seal, and registering it also activates a Pending membership → Active (emits MemberActivatedEvent). Hybrid device-trust enrollment tokens ride the same flow. This modal is a required onboarding step and the member entry-gate (see Seals & integrity).
Visual seals (the designed stamp)
Section titled “Visual seals (the designed stamp)”Distinct from the cryptographic seals above — these are the rendered SVG stamps drawn on approval documents. Full model: Seals & integrity → the visual seal designer.
| Method · Route | Purpose | Source |
|---|---|---|
POST /api/org/{slug}/settings/seal | Upload/replace the company seal image; stored on Organization.SealUrl (R2 logos/orgs/{id}/…). Owner/admin. Emits OrganizationSettingsUpdatedEvent (Category Seal). | OrgLogoEndpoints.cs |
DELETE /api/org/{slug}/settings/seal | Remove the company seal. | OrgLogoEndpoints.cs |
PUT /api/org/{slug}/members/{connectedId}/signature | Set the caller’s own personal signature/seal — {kind, spec} where kind = signature / seal / draw / image / none. Self-only; 8 KB cap; JSON-validated. Stored on User.SignatureSpec. Emits org.member.signature_changed (ORG025). | OrgEndpoints.cs |
POST /api/org/{slug}/members/{connectedId}/signature/image | Upload a raster/SVG personal seal image (R2 logos/users/{uid}/…). Self-only. | OrgEndpoints.cs |
The designed spec is exposed on /me (UserInfo.SignatureSpec) and rendered by the shared PersonalSignature component wherever a seal appears.