recovery
client.recovery runs break-glass recovery. An Owner asks to recover a key domain, or the whole tenant, to a new domain owner. Custodians take part with their backup key shares. The last custodian of the quorum rebuilds the key.
ask
ask starts a ceremony. An Owner calls it after a fresh multi-factor sign-in. The request is recorded in the Seald Healthcare Cloud and in Seald Healthcare’s own records at once, before anything else happens. The asking Owner may be the new domain owner.
ask(request: { domains: Locator[] | 'all'; newOwner: Person; reason: string; reference: string }): Promise<Decided<Ceremony>>;func ask(domains: DomainScope, newOwner: Person, reason: String, reference: String) async throws -> Decided<Ceremony>
enum DomainScope { case locators([Locator]); case all }suspend fun ask(domains: DomainScope, newOwner: Person, reason: String, reference: String): Decided<Ceremony>
sealed interface DomainScope { data class Locators(val locators: List<Locator>) : DomainScope object All : DomainScope}| Parameter | Type | Description |
|---|---|---|
domains | Locator[] or "all" | The key domains to recover, or every key domain in the tenant. |
newOwner | Person | Who becomes domain owner. May be the Owner who asks. |
reason | string | Why the ceremony is asked for. |
reference | string | The ticket or record this ceremony is tied to. |
Returns: A Decided<Ceremony>.
Records: Recover. See Audit actions.
Who may call it: The Owner role.
Errors: no-session, unreachable, canceled.
ceremonies
ceremonies returns the ceremonies that every Owner and custodian sees.
ceremonies(): Promise<Ceremony[]>;func ceremonies() async throws -> [Ceremony]suspend fun ceremonies(): List<Ceremony>Returns: Every Ceremony an Owner or custodian may see.
Records: Nothing. Not a decision.
Errors: no-session, unreachable.
cancel
cancel cancels a ceremony before the quorum completes.
cancel(ceremonyId: string): Promise<void>;func cancel(_ ceremonyId: String) async throwssuspend fun cancel(ceremonyId: String)| Parameter | Type | Description |
|---|---|---|
ceremonyId | string | The ceremony to cancel. |
Returns: Nothing.
Records: Nothing. Not a decision.
Errors: no-session, unreachable, not-found.
takePart
takePart agrees to a ceremony and presents the custodian’s share. The last custodian’s Client in the quorum holds the share in memory until the token arrives. It then rebuilds the key. This call resolves only once the recovery is committed. If the application closes before that, the custodian must present the share again.
takePart(ceremonyId: string, share: ShareInput): Promise<Participation>;func takePart(_ ceremonyId: String, share: ShareInput) async throws -> Participationsuspend fun takePart(ceremonyId: String, share: ShareInput): Participation| Parameter | Type | Description |
|---|---|---|
ceremonyId | string | The ceremony to take part in. |
share | ShareInput | This custodian’s backup key share, from backupKey. |
Returns: A Participation: wrapped for every custodian but the last, rebuilt for the last of the quorum.
Records: Nothing. Not a decision.
Errors: no-session, unreachable, not-found.
refuse
refuse refuses to take part in a ceremony.
refuse(ceremonyId: string): Promise<void>;func refuse(_ ceremonyId: String) async throwssuspend fun refuse(ceremonyId: String)| Parameter | Type | Description |
|---|---|---|
ceremonyId | string | The ceremony to refuse. |
Returns: Nothing.
Records: Nothing. Not a decision.
Errors: no-session, unreachable, not-found.
Types
Ceremony
interface Ceremony { ceremonyId: string; kind: 'recovery' | 'custodian-replacement'; state: 'open' | 'quorum' | 'completed' | 'canceled' | 'lapsed'; askedBy: RecipientId; reason: string; reference: string; domains: Locator[] | 'all'; newOwner?: Person; custodians: { person: Person; state: 'waiting' | 'agreed' | 'refused' }[]; quorum: number; openedAt: Date; lapsesAt: Date;}struct Ceremony { let ceremonyId: String let kind: Kind let state: State let askedBy: RecipientId let reason: String let reference: String let domains: DomainScope let newOwner: Person? let custodians: [(person: Person, state: CustodianState)] let quorum: Int let openedAt: Date let lapsesAt: Date
enum Kind { case recovery, custodianReplacement } enum State { case open, quorum, completed, canceled, lapsed } enum CustodianState { case waiting, agreed, refused }}data class Ceremony( val ceremonyId: String, val kind: Kind, val state: State, val askedBy: RecipientId, val reason: String, val reference: String, val domains: DomainScope, val newOwner: Person?, val custodians: List<CustodianEntry>, val quorum: Int, val openedAt: Instant, val lapsesAt: Instant,) { enum class Kind { RECOVERY, CUSTODIAN_REPLACEMENT } enum class State { OPEN, QUORUM, COMPLETED, CANCELED, LAPSED } enum class CustodianState { WAITING, AGREED, REFUSED } data class CustodianEntry(val person: Person, val state: CustodianState)}| Field | Type | Description |
|---|---|---|
ceremonyId | string | Identifies the ceremony. |
kind | "recovery" or "custodian-replacement" | What the ceremony is for. |
state | one of the five states | Where the ceremony stands. |
askedBy | RecipientId | Who asked for it. |
reason | string | Why it was asked for. |
reference | string | The ticket or record it is tied to. |
domains | Locator[] or "all" | The key domains to recover. |
newOwner | Person, optional | Who becomes domain owner, for a recovery ceremony. |
custodians | list of person and state | Each custodian and whether they are waiting, agreed or refused. |
quorum | number | How many custodians must agree. |
openedAt | date | When the ceremony opened. |
lapsesAt | date | When it lapses unfinished. |
Participation
type Participation = | { role: 'wrapped' } | { role: 'rebuilt'; domains: Locator[] };enum Participation { case wrapped case rebuilt(domains: [Locator])}sealed interface Participation { object Wrapped : Participation data class Rebuilt(val domains: List<Locator>) : Participation}| Case | Payload | Description |
|---|---|---|
wrapped | none | This custodian’s share went to the others. The SDK then discarded it from this device’s memory. |
rebuilt | domains | This custodian’s Client is the last of the quorum. It held the share in memory, rebuilt the key once the token arrived, gave the new domain owner access, then discarded every piece from memory. |