import { type DidOptions } from "./signed-token.js"; export declare const DECISION_REQUEST_CONTRACT = "mandaitor.decision-request/v1"; export declare const DECISION_CONTRACT = "mandaitor.decision/v1"; export declare const DECISION_AUTHORIZATION_CONTRACT = "mandaitor.decision-authorization/v1"; export declare const DECISION_AUTHORIZATION_TYP = "mandaitor-authorization+jwt"; /** The authorization key's fragment in the issuer's DID document. */ export declare const DECISION_AUTHORIZATION_KEY_FRAGMENT = "authorization-key-1"; /** An amount: an ISO 4217 code and a non-negative decimal string, never a JSON number. */ export interface Money { currency: string; value: string; } /** A fact the enforcement point read: a string, a safe integer, a boolean, or money. */ export type DecisionFactValue = string | number | boolean | Money; /** What the enforcement point asks Mandaitor to decide (`mandaitor.decision-request/v1`). */ export interface DecisionRequest { /** The agent the enforcement point acts for, by its DID. */ agent: string; /** A taxonomy business action, e.g. `procurement.requisition.release`. */ action: string; /** The one resource the operation acts on. No `*`, no `{placeholder}`. */ resource: string; /** * What the enforcement point read from its own system, by name. `amount`, * when a mandate limits amounts, is money. All of them are bound into the * request digest. */ facts: Record; /** The enforcement point itself: the only one that may act on the authorization. */ audience: string; /** The mandate the enforcement point believes covers the operation. A hint only. */ mandate_id?: string; /** Recorded with the decision; never used to decide. */ purpose?: string; } /** Why a person would have to approve. Approvals are not raised from a decision request. */ export type DecisionApprovalRule = "AMOUNT_ABOVE_THRESHOLD" | "REQUIRE_MFA" | "ACTION_REQUIRES_APPROVAL"; /** Mandaitor's answer (`mandaitor.decision/v1`). Only an ALLOW carries an authorization. */ export interface Decision { contract: typeof DECISION_CONTRACT; decision: "ALLOW" | "DENY" | "REQUIRE_APPROVAL"; /** `ALLOWED`, `APPROVAL_REQUIRED`, or the reason a DENY gives, e.g. `NO_COVERING_MANDATE`. */ code: string; reason: string; /** The request digest, as Mandaitor computed it. */ request_digest: string; /** The decision's event on the audit chain. */ event_id: string; decided_at: string; /** The mandate the decision rests on, or the one a denial is reported against. */ mandate_id?: string; /** In ALLOW: the id the authorization is redeemed by (its `jti`). */ decision_id?: string; /** In ALLOW: the signed authorization, a compact JWS. */ authorization?: string; /** In ALLOW: the last moment the authorization may be redeemed. */ expires_at?: string; /** In REQUIRE_APPROVAL: why a person would have to approve. No approval is raised. */ approval_rules?: DecisionApprovalRule[]; } /** A redeemed authorization: the enforcement point may act on it now, once. */ export interface DecisionRedemption { decision_id: string; redeemed_at: string; /** The redemption's event on the audit chain. */ event_id: string; } /** The claims of a decision authorization, as Mandaitor signs them. */ export interface DecisionAuthorizationClaims { /** The issuer's DID. */ iss: string; /** The enforcement point the request named. */ aud: string; /** The agent's DID. */ sub: string; iat: number; exp: number; /** The decision's id: `dec_` and a ULID. */ jti: string; contract: typeof DECISION_AUTHORIZATION_CONTRACT; tenant_id: string; request_digest: string; action: string; resource: string; mandate_id: string; event_id: string; } /** What an authorization must say. Every field is optional. */ export interface AuthorizationExpectation { tenant_id?: string; /** The agent's DID. */ agent?: string; /** The digest of the operation about to be performed: {@link decisionRequestDigest}. */ request_digest?: string; action?: string; resource?: string; } /** Options for {@link verifyDecisionAuthorization}. */ export interface AuthorizationVerifyOptions extends DidOptions { /** The enforcement point's own name, as it sent it in `audience`. Required. */ audience: string; expected?: AuthorizationExpectation; /** Clock skew tolerance for `iat` and `exp`, in seconds (default 60). */ clockSkewSeconds?: number; /** The current time, in Unix seconds, for testing. */ currentTime?: number; } export interface AuthorizationVerificationResult { valid: boolean; /** The decoded claims, for inspection even when invalid; null when undecodable. */ claims: Partial | null; /** Each problem found; empty when valid. */ errors: string[]; } /** * The request digest of a decision request, as Mandaitor computes it: the * SHA-256 of the RFC 8785 form of the contract, the tenant, the agent, the * action, the resource, the facts and the audience. `mandate_id` and * `purpose` are not part of it. The authorization carries it, and the * enforcement point redeems the authorization with it. */ export declare function decisionRequestDigest(tenantId: string, request: Pick): Promise; /** * Verifies a decision authorization: that it is an authorization and nothing * else, that the issuer's authorization key signed it, that it is for this * enforcement point and still in its five minutes, and that it says what * `options.expected` says. It does not redeem it: an authorization is acted * on only after {@link MandaitorClient.redeemDecision} succeeds. */ export declare function verifyDecisionAuthorization(token: string, options: AuthorizationVerifyOptions): Promise; /** * Verifies the authorization a decision came with, against the request the * enforcement point is about to act on: its digest, agent, action, resource * and audience, for `tenantId`. Invalid when the decision carries none. */ export declare function verifyAuthorizationForRequest(decision: Pick, tenantId: string, request: Pick, options?: Omit): Promise; //# sourceMappingURL=decisions.d.ts.map