@atlasent/sdk 2.5.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/dist/behavior.cjs +2 -1
- package/dist/behavior.cjs.map +1 -1
- package/dist/behavior.d.cts +32 -5
- package/dist/behavior.d.ts +32 -5
- package/dist/behavior.js +2 -1
- package/dist/behavior.js.map +1 -1
- package/dist/hono.cjs +1198 -29
- package/dist/hono.cjs.map +1 -1
- package/dist/hono.d.cts +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/hono.js +1197 -29
- package/dist/hono.js.map +1 -1
- package/dist/index.cjs +6033 -1189
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4062 -766
- package/dist/index.d.ts +4062 -766
- package/dist/index.js +5939 -1188
- package/dist/index.js.map +1 -1
- package/dist/{protect-DiRVfVLq.d.cts → protect-B6w-WQMB.d.cts} +886 -206
- package/dist/{protect-DiRVfVLq.d.ts → protect-B6w-WQMB.d.ts} +886 -206
- package/package.json +6 -1
|
@@ -45,7 +45,7 @@ declare class StreamParseError extends Error {
|
|
|
45
45
|
constructor(rawData: string, cause?: unknown);
|
|
46
46
|
}
|
|
47
47
|
/** Discriminator for {@link AtlaSentError.code}. */
|
|
48
|
-
type AtlaSentErrorCode = "invalid_api_key" | "forbidden" | "rate_limited" | "timeout" | "network" | "bad_response" | "bad_request" | "server_error" | "feature_disabled";
|
|
48
|
+
type AtlaSentErrorCode = "invalid_api_key" | "forbidden" | "rate_limited" | "timeout" | "network" | "bad_response" | "bad_request" | "server_error" | "feature_disabled" | "claim_evidence_incomplete";
|
|
49
49
|
/** Initialization options for {@link AtlaSentError}. */
|
|
50
50
|
interface AtlaSentErrorInit {
|
|
51
51
|
status?: number;
|
|
@@ -97,7 +97,7 @@ type AtlaSentDecision = "deny" | "hold" | "escalate";
|
|
|
97
97
|
* `atlasent/docs/REVOCATION_RUNBOOK.md` for the operator-facing
|
|
98
98
|
* matrix this discriminator drives.
|
|
99
99
|
*/
|
|
100
|
-
type PermitOutcome = "permit_consumed" | "permit_expired" | "permit_revoked" | "permit_not_found";
|
|
100
|
+
type PermitOutcome = "permit_consumed" | "permit_expired" | "permit_revoked" | "permit_not_found" | "permit_signing_key_revoked";
|
|
101
101
|
/**
|
|
102
102
|
* Map a server-supplied `outcome` string to {@link PermitOutcome}.
|
|
103
103
|
*
|
|
@@ -169,6 +169,11 @@ declare class AtlaSentDeniedError extends AtlaSentError {
|
|
|
169
169
|
* (typo, cross-tenant lookup, or pre-issuance race).
|
|
170
170
|
*/
|
|
171
171
|
get isNotFound(): boolean;
|
|
172
|
+
/**
|
|
173
|
+
* `true` when the permit's signing key KID appears in the
|
|
174
|
+
* trust-root revocation list (ADR-005 D3 R2/R3 key rotation).
|
|
175
|
+
*/
|
|
176
|
+
get isSigningKeyRevoked(): boolean;
|
|
172
177
|
}
|
|
173
178
|
/** Initialization options for {@link AtlaSentEscalateError}. */
|
|
174
179
|
interface AtlaSentEscalateErrorInit {
|
|
@@ -237,6 +242,50 @@ declare class PermitRevoked extends AtlaSentError {
|
|
|
237
242
|
readonly revocationId: string | undefined;
|
|
238
243
|
constructor(permitId: string, revocationId?: string);
|
|
239
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Initialization options for {@link BundleVerificationError}.
|
|
247
|
+
*/
|
|
248
|
+
interface BundleVerificationErrorInit {
|
|
249
|
+
/**
|
|
250
|
+
* Machine-readable reason code:
|
|
251
|
+
* - `trust_snapshot_expired`: the snapshot's `valid_until` has passed
|
|
252
|
+
* and `allowExpiredSnapshot` was not set.
|
|
253
|
+
* - `key_revoked`: the bundle's `signing_key_id` appears in
|
|
254
|
+
* `revoked_keys` of the active trust snapshot.
|
|
255
|
+
* - `key_role_mismatch`: the signing key's `role` is not `"R3_audit"`.
|
|
256
|
+
*/
|
|
257
|
+
reason: "trust_snapshot_expired" | "key_revoked" | "key_role_mismatch";
|
|
258
|
+
/** ISO-8601 `valid_until` of the snapshot that caused the failure. */
|
|
259
|
+
snapshotValidUntil?: string;
|
|
260
|
+
/** ISO-8601 `issued_at` of the snapshot (its fetch/pin time). */
|
|
261
|
+
snapshotFetchedAt?: string;
|
|
262
|
+
/** Whether the snapshot came from the bundled vendor files or a live refresh. */
|
|
263
|
+
snapshotSource?: "pinned" | "live";
|
|
264
|
+
/** Which key id was revoked or role-mismatched, when applicable. */
|
|
265
|
+
kid?: string;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Thrown by {@link verifyAuditBundle} / {@link verifyBundle} when the
|
|
269
|
+
* active trust-root snapshot is expired (ADR-005 D3) or the bundle's
|
|
270
|
+
* signing key is revoked / has the wrong role.
|
|
271
|
+
*
|
|
272
|
+
* This error is **always thrown** — it is never returned as a
|
|
273
|
+
* {@link BundleVerificationResult} because ADR-005 D3 requires that
|
|
274
|
+
* an expired snapshot or revoked key constitutes a hard enforcement
|
|
275
|
+
* action, not a soft verification failure.
|
|
276
|
+
*
|
|
277
|
+
* To opt out of fail-closed expiry (air-gap / offline use), pass
|
|
278
|
+
* `allowExpiredSnapshot: true` to `verifyBundle`.
|
|
279
|
+
*/
|
|
280
|
+
declare class BundleVerificationError extends AtlaSentError {
|
|
281
|
+
name: string;
|
|
282
|
+
readonly reason: BundleVerificationErrorInit["reason"];
|
|
283
|
+
readonly snapshotValidUntil: string | undefined;
|
|
284
|
+
readonly snapshotFetchedAt: string | undefined;
|
|
285
|
+
readonly snapshotSource: "pinned" | "live" | undefined;
|
|
286
|
+
readonly kid: string | undefined;
|
|
287
|
+
constructor(init: BundleVerificationErrorInit);
|
|
288
|
+
}
|
|
240
289
|
|
|
241
290
|
/**
|
|
242
291
|
* Retry-policy helpers for the AtlaSent TypeScript SDK.
|
|
@@ -268,18 +317,18 @@ declare class PermitRevoked extends AtlaSentError {
|
|
|
268
317
|
* It avoids thundering-herd retries from many SDK instances that hit
|
|
269
318
|
* a 429 in the same window.
|
|
270
319
|
*
|
|
271
|
-
* Default schedule
|
|
272
|
-
* attempt 0 (1st retry): base
|
|
273
|
-
* attempt 1 (2nd retry): base
|
|
274
|
-
*
|
|
275
|
-
* attempt 3 (4th retry): capped at 16 000 ms, jittered in [0, 16 000)
|
|
276
|
-
* Total attempts (including initial): 4
|
|
320
|
+
* Default schedule:
|
|
321
|
+
* attempt 0 (1st retry): base 250 ms, jittered in [0, 250)
|
|
322
|
+
* attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)
|
|
323
|
+
* Total attempts (including initial): 3
|
|
277
324
|
*/
|
|
278
325
|
/**
|
|
279
326
|
* Defaults for {@link RetryPolicy}.
|
|
280
327
|
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
328
|
+
* Exponential backoff with full jitter, base 250 ms, capped at 10 s:
|
|
329
|
+
* attempt 0 (1st retry): base 250 ms, jittered in [0, 250)
|
|
330
|
+
* attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)
|
|
331
|
+
* Total attempts (including initial): 3
|
|
283
332
|
*/
|
|
284
333
|
declare const DEFAULT_RETRY_POLICY: Required<RetryPolicy>;
|
|
285
334
|
/**
|
|
@@ -686,6 +735,59 @@ interface DeployGateResponse {
|
|
|
686
735
|
/** Best-effort audit/evidence metadata available to the SDK. */
|
|
687
736
|
evidence: DeployGateEvidence;
|
|
688
737
|
}
|
|
738
|
+
/**
|
|
739
|
+
* Frozen BVS snapshot wire shape (BI4).
|
|
740
|
+
* Carried in {@link EvaluateRequest}.context.bvsSnapshot when
|
|
741
|
+
* the `behavior_conditioning` flag is enabled for the tenant.
|
|
742
|
+
* Produced by behavior-insights GET /api/patterns/snapshot/:userId
|
|
743
|
+
* and attached via `@atlasent/behavior` attachToEvaluate().
|
|
744
|
+
*/
|
|
745
|
+
interface BvsSnapshot {
|
|
746
|
+
user_id: string;
|
|
747
|
+
/** Factor model output — keyed by BVS factor slug, value is score 0-1. */
|
|
748
|
+
factors: Record<string, number>;
|
|
749
|
+
/** Aggregate confidence score (0-1). Decays on a 60-day half-life. */
|
|
750
|
+
confidence: number;
|
|
751
|
+
/** True when the aggregate is fresh-and-thin (too few events to trust). */
|
|
752
|
+
confidence_low: boolean;
|
|
753
|
+
/** ISO-8601 timestamp of the compute run that produced this snapshot. */
|
|
754
|
+
computed_at: string;
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Consent-class projection (BI5) — the privacy-safe aggregate shape that
|
|
758
|
+
* third-party apps (LedgersMe, hiCoach, echobloom) receive when reading a
|
|
759
|
+
* user's behavioral summary. Counts and timestamps only; no raw free-text.
|
|
760
|
+
* Produced by behavior-insights `/api/patterns/summary/:userId` and fetched
|
|
761
|
+
* via `@atlasent/behavior` getStateSummary(). The SDK enforces
|
|
762
|
+
* {@link https://github.com/AtlaSent-Systems-Inc/atlasent-sdk | assertNoRawText}
|
|
763
|
+
* client-side before returning this shape to callers.
|
|
764
|
+
*/
|
|
765
|
+
interface ConsentClassProjection {
|
|
766
|
+
user_id: string;
|
|
767
|
+
window_start: string;
|
|
768
|
+
window_end: string;
|
|
769
|
+
event_count: number;
|
|
770
|
+
category_counts: Partial<Record<string, number>>;
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Proof that a specific actor consumed a specific permit for a specific
|
|
774
|
+
* action_type. Pass an array of these as `completion_proofs` on an evaluate
|
|
775
|
+
* request to satisfy multi-actor quorum dependencies.
|
|
776
|
+
*
|
|
777
|
+
* The runtime verifies each proof via two gates (both must pass):
|
|
778
|
+
* 1. A `permit_uses` row exists for `permit_id` (permit was consumed).
|
|
779
|
+
* 2. An `execution_evaluations` row is bound to `actor_id` + `action_type`
|
|
780
|
+
* for the same permit (actor/action binding — Codex P1 #1148 FIX #3).
|
|
781
|
+
* Proofs that fail either gate are silently dropped (fail-closed).
|
|
782
|
+
*/
|
|
783
|
+
interface CompletionProof {
|
|
784
|
+
/** The action_type (slug) that was completed by the prior actor. */
|
|
785
|
+
action_type: string;
|
|
786
|
+
/** The actor who completed the action. */
|
|
787
|
+
actor_id: string;
|
|
788
|
+
/** The permit token (or its hash) issued when the action was permitted. */
|
|
789
|
+
permit_id: string;
|
|
790
|
+
}
|
|
689
791
|
/** Input to {@link AtlaSentClient.evaluate}. */
|
|
690
792
|
interface EvaluateRequest {
|
|
691
793
|
/** Identifier of the calling agent (e.g. "clinical-data-agent"). */
|
|
@@ -694,6 +796,63 @@ interface EvaluateRequest {
|
|
|
694
796
|
action: string;
|
|
695
797
|
/** Arbitrary policy context (user, environment, resource IDs). */
|
|
696
798
|
context?: Record<string, unknown>;
|
|
799
|
+
/**
|
|
800
|
+
* When `true`, the server populates `riskEnvelope.factors` with a
|
|
801
|
+
* per-factor breakdown of the weighted risk score. Omit (or `false`)
|
|
802
|
+
* to keep response payloads small.
|
|
803
|
+
*/
|
|
804
|
+
explain?: boolean;
|
|
805
|
+
/** Deployment environment where the action executes (e.g. `"production"`). */
|
|
806
|
+
environment?: string;
|
|
807
|
+
/** Structured resource descriptor. Prefer over embedding resource info in `context`. */
|
|
808
|
+
resource?: {
|
|
809
|
+
type: string;
|
|
810
|
+
id?: string;
|
|
811
|
+
attributes?: Record<string, unknown>;
|
|
812
|
+
};
|
|
813
|
+
/** Snapshot of the resource state before the proposed action. Enables state-transition-aware policy evaluation. */
|
|
814
|
+
current_state?: {
|
|
815
|
+
description: string;
|
|
816
|
+
attributes?: Record<string, unknown>;
|
|
817
|
+
};
|
|
818
|
+
/** Desired resource state after the action executes. */
|
|
819
|
+
proposed_state?: {
|
|
820
|
+
description: string;
|
|
821
|
+
attributes?: Record<string, unknown>;
|
|
822
|
+
};
|
|
823
|
+
/** Execution surface binding — identifies the CI/CD adapter, DB driver, or enforcement point. */
|
|
824
|
+
execution_binding?: {
|
|
825
|
+
kind: string;
|
|
826
|
+
adapter_version?: string;
|
|
827
|
+
resource_id?: string;
|
|
828
|
+
enforcement_point?: string;
|
|
829
|
+
};
|
|
830
|
+
/** The desired end-state the actor wants the resource to reach. Enables trajectory-aware authorization. */
|
|
831
|
+
desired_state?: {
|
|
832
|
+
description: string;
|
|
833
|
+
attributes?: Record<string, unknown>;
|
|
834
|
+
fingerprint?: string;
|
|
835
|
+
};
|
|
836
|
+
/** Actor-proposed execution path from current_state to desired_state. The engine returns an authorized_trajectory that may differ. */
|
|
837
|
+
proposed_trajectory?: {
|
|
838
|
+
steps: Array<{
|
|
839
|
+
step: string;
|
|
840
|
+
description?: string;
|
|
841
|
+
required: boolean;
|
|
842
|
+
time_limit_seconds?: number;
|
|
843
|
+
authorized_by?: string;
|
|
844
|
+
constraints?: Record<string, unknown>;
|
|
845
|
+
}>;
|
|
846
|
+
description?: string;
|
|
847
|
+
};
|
|
848
|
+
/**
|
|
849
|
+
* Multi-actor quorum completion proofs. Supply one entry per prior actor
|
|
850
|
+
* whose completed action this evaluation depends on. The runtime verifies
|
|
851
|
+
* each proof (consumed-permit gate + actor/action binding gate) and counts
|
|
852
|
+
* only valid proofs toward quorum. Absent or empty → no quorum proofs
|
|
853
|
+
* submitted (no behavioral change for non-quorum dependencies).
|
|
854
|
+
*/
|
|
855
|
+
completion_proofs?: CompletionProof[];
|
|
697
856
|
}
|
|
698
857
|
/**
|
|
699
858
|
* Slim permit object embedded in {@link EvaluateResponse} when the decision
|
|
@@ -793,6 +952,97 @@ interface EvaluateResponse {
|
|
|
793
952
|
* `X-RateLimit-*` headers. `null` when the server didn't emit them.
|
|
794
953
|
*/
|
|
795
954
|
rateLimit: RateLimitState | null;
|
|
955
|
+
/**
|
|
956
|
+
* Risk envelope summary from the policy engine. Present on all responses
|
|
957
|
+
* from engine version wire-v1@1.0.0+. Provides the weighted risk score,
|
|
958
|
+
* the pre/post-promotion decisions, and (when evaluate was called with
|
|
959
|
+
* `explain: true`) a per-factor breakdown.
|
|
960
|
+
*
|
|
961
|
+
* The envelope can only raise severity — it structurally cannot soften
|
|
962
|
+
* a deny to allow. When `promoted` is true the live `decision` was
|
|
963
|
+
* upgraded from `engineDecision` to `envelopeDecision`.
|
|
964
|
+
*/
|
|
965
|
+
riskEnvelope?: EvaluateRiskEnvelope;
|
|
966
|
+
/**
|
|
967
|
+
* Resolved risk class from the evaluation engine.
|
|
968
|
+
* One of `"critical"`, `"high"`, `"medium"`, `"low"`.
|
|
969
|
+
* Present when the risk envelope assigns a class.
|
|
970
|
+
*/
|
|
971
|
+
riskClass?: string;
|
|
972
|
+
/**
|
|
973
|
+
* WHY this permit was issued — the authority kind and a reference to the
|
|
974
|
+
* authorizing entity. Present on `allow` decisions when the control plane
|
|
975
|
+
* attaches explicit authority provenance.
|
|
976
|
+
*/
|
|
977
|
+
authorityBasis?: {
|
|
978
|
+
kind: "policy" | "approval" | "emergency" | "maintenance_window" | "delegation" | "quorum";
|
|
979
|
+
reference?: string;
|
|
980
|
+
grantedBy?: string;
|
|
981
|
+
rationale?: string;
|
|
982
|
+
expiresAt?: string;
|
|
983
|
+
};
|
|
984
|
+
/**
|
|
985
|
+
* ID of the HITL escalation auto-created by the control plane.
|
|
986
|
+
* Present iff `decision === "hold"`. Poll `GET /v1/escalations/{id}`
|
|
987
|
+
* for resolution status.
|
|
988
|
+
*/
|
|
989
|
+
escalationId?: string;
|
|
990
|
+
/**
|
|
991
|
+
* Authorized execution trajectory returned when the engine approved a
|
|
992
|
+
* `proposed_trajectory`. Present only on `allow` decisions.
|
|
993
|
+
* May differ from what was proposed — the engine may add checkpoints,
|
|
994
|
+
* restrict steps, or tighten time limits. Follow this trajectory exactly;
|
|
995
|
+
* call `POST /v1/trajectory-verify` at each step to confirm on_trajectory.
|
|
996
|
+
*/
|
|
997
|
+
authorized_trajectory?: {
|
|
998
|
+
trajectory_id: string;
|
|
999
|
+
steps: Array<{
|
|
1000
|
+
step: string;
|
|
1001
|
+
description?: string;
|
|
1002
|
+
required: boolean;
|
|
1003
|
+
time_limit_seconds?: number;
|
|
1004
|
+
authorized_by?: string;
|
|
1005
|
+
constraints?: Record<string, unknown>;
|
|
1006
|
+
expected_intermediate_state?: {
|
|
1007
|
+
description: string;
|
|
1008
|
+
attributes?: Record<string, unknown>;
|
|
1009
|
+
fingerprint?: string;
|
|
1010
|
+
};
|
|
1011
|
+
}>;
|
|
1012
|
+
description?: string;
|
|
1013
|
+
forbidden_states?: Array<{
|
|
1014
|
+
description: string;
|
|
1015
|
+
attributes?: Record<string, unknown>;
|
|
1016
|
+
fingerprint?: string;
|
|
1017
|
+
}>;
|
|
1018
|
+
expires_at: string;
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
/** Per-factor contribution in a {@link EvaluateRiskEnvelope}. */
|
|
1022
|
+
interface EvaluateRiskEnvelopeFactor {
|
|
1023
|
+
/** Factor identifier, e.g. `"ACTION_SENSITIVITY"`. */
|
|
1024
|
+
factor: string;
|
|
1025
|
+
/** Factor score in [0, 1]. Higher = more risk. */
|
|
1026
|
+
value: number;
|
|
1027
|
+
/** Configured weight for this factor. */
|
|
1028
|
+
weight: number;
|
|
1029
|
+
/** Human-readable explanation for the score. */
|
|
1030
|
+
reason: string;
|
|
1031
|
+
}
|
|
1032
|
+
/** Risk envelope summary returned in a top-level {@link EvaluateResponse}. */
|
|
1033
|
+
interface EvaluateRiskEnvelope {
|
|
1034
|
+
/** Weighted risk score in [0, 1]. Score ≥ 0.70 triggers a hold. */
|
|
1035
|
+
weightedScore: number;
|
|
1036
|
+
/** Policy engine decision before envelope promotion. */
|
|
1037
|
+
engineDecision: Decision;
|
|
1038
|
+
/** Decision resolved by the risk envelope. */
|
|
1039
|
+
envelopeDecision: Decision;
|
|
1040
|
+
/** `true` when the envelope raised the decision's severity (most-restrictive-wins). */
|
|
1041
|
+
promoted: boolean;
|
|
1042
|
+
/** Deny codes that unconditionally block regardless of score. */
|
|
1043
|
+
hardBlocks: string[];
|
|
1044
|
+
/** Per-factor breakdown. Present only when `explain: true` was passed. */
|
|
1045
|
+
factors?: EvaluateRiskEnvelopeFactor[];
|
|
796
1046
|
}
|
|
797
1047
|
/** Input to {@link AtlaSentClient.verifyPermit}. */
|
|
798
1048
|
interface VerifyPermitRequest {
|
|
@@ -838,6 +1088,11 @@ interface VerifyPermitResponse {
|
|
|
838
1088
|
permitHash: string;
|
|
839
1089
|
/** ISO 8601 timestamp of the verification. */
|
|
840
1090
|
timestamp: string;
|
|
1091
|
+
/**
|
|
1092
|
+
* ISO-8601 expiration timestamp of the permit. `null` on pre-rollout
|
|
1093
|
+
* server versions that do not yet surface this field.
|
|
1094
|
+
*/
|
|
1095
|
+
expiresAt: string | null;
|
|
841
1096
|
/**
|
|
842
1097
|
* Per-key rate-limit state for this request's response, parsed from
|
|
843
1098
|
* `X-RateLimit-*` headers. `null` when the server didn't emit them.
|
|
@@ -849,18 +1104,13 @@ interface VerifyPermitResponse {
|
|
|
849
1104
|
* key the client was constructed with. Returned by `GET /v1/api-key-self`.
|
|
850
1105
|
*
|
|
851
1106
|
* Never includes the raw key or its hash — introspection is intentionally
|
|
852
|
-
* read-only and safe to surface in operator dashboards.
|
|
853
|
-
* - "which key am I?" debugging
|
|
854
|
-
* - IP_NOT_ALLOWED failures — `clientIp` is the IP the server observed
|
|
855
|
-
* - proactive expiry warnings — `expiresAt` is the server-stored expiry
|
|
856
|
-
* (`null` means the key does not auto-expire)
|
|
857
|
-
* - verifying scopes before attempting a scope-gated action
|
|
1107
|
+
* read-only and safe to surface in operator dashboards.
|
|
858
1108
|
*/
|
|
859
1109
|
interface ApiKeySelfResponse {
|
|
860
1110
|
/** Server-side UUID of the api_keys row for this key. */
|
|
861
1111
|
keyId: string;
|
|
862
1112
|
/** Organization the key belongs to. */
|
|
863
|
-
|
|
1113
|
+
orgId: string;
|
|
864
1114
|
/** "live" or "test" (or any future environment label the server introduces). */
|
|
865
1115
|
environment: string;
|
|
866
1116
|
/** Granted scopes — e.g. ["evaluate", "audit.read"]. */
|
|
@@ -885,24 +1135,16 @@ interface ApiKeySelfResponse {
|
|
|
885
1135
|
/**
|
|
886
1136
|
* Result of {@link AtlaSentClient.listAuditEvents}. Extends the raw
|
|
887
1137
|
* wire page with a camelCase `rateLimit` alongside the snake_case
|
|
888
|
-
* wire fields
|
|
889
|
-
* untouched so callers that pass it to the offline verifier get
|
|
890
|
-
* byte-identical behaviour.
|
|
1138
|
+
* wire fields.
|
|
891
1139
|
*/
|
|
892
1140
|
interface AuditEventsResult extends AuditEventsPage {
|
|
893
|
-
/**
|
|
894
|
-
* Per-key rate-limit state for this request's response, parsed from
|
|
895
|
-
* `X-RateLimit-*` headers. `null` when the server didn't emit them.
|
|
896
|
-
*/
|
|
897
1141
|
rateLimit: RateLimitState | null;
|
|
898
1142
|
}
|
|
899
1143
|
/**
|
|
900
|
-
* Filter accepted by {@link AtlaSentClient.createAuditExport}.
|
|
901
|
-
* are snake_case to match the server's `POST /v1-audit/exports`
|
|
902
|
-
* request body; an empty object requests a full-org bundle.
|
|
1144
|
+
* Filter accepted by {@link AtlaSentClient.createAuditExport}.
|
|
903
1145
|
*/
|
|
904
1146
|
interface AuditExportRequest {
|
|
905
|
-
/** Comma-joined list of event types to include
|
|
1147
|
+
/** Comma-joined list of event types to include. */
|
|
906
1148
|
types?: string;
|
|
907
1149
|
/** Filter to a single actor. */
|
|
908
1150
|
actor_id?: string;
|
|
@@ -912,18 +1154,9 @@ interface AuditExportRequest {
|
|
|
912
1154
|
to?: string;
|
|
913
1155
|
}
|
|
914
1156
|
/**
|
|
915
|
-
* Result of {@link AtlaSentClient.createAuditExport}.
|
|
916
|
-
* signed bundle shape with a camelCase `rateLimit`. The signed
|
|
917
|
-
* envelope fields (`export_id`, `org_id`, `chain_head_hash`,
|
|
918
|
-
* `event_count`, `signed_at`, `events`, `signature`) are preserved
|
|
919
|
-
* byte-for-byte so the object can be handed straight to
|
|
920
|
-
* `verifyAuditBundle(bundle, keys)`.
|
|
1157
|
+
* Result of {@link AtlaSentClient.createAuditExport}.
|
|
921
1158
|
*/
|
|
922
1159
|
interface AuditExportResult extends AuditExport {
|
|
923
|
-
/**
|
|
924
|
-
* Per-key rate-limit state for this request's response, parsed from
|
|
925
|
-
* `X-RateLimit-*` headers. `null` when the server didn't emit them.
|
|
926
|
-
*/
|
|
927
1160
|
rateLimit: RateLimitState | null;
|
|
928
1161
|
}
|
|
929
1162
|
/** Constructor options for {@link AtlaSentClient}. */
|
|
@@ -948,16 +1181,24 @@ interface AtlaSentClientOptions {
|
|
|
948
1181
|
* Pass `{ maxAttempts: 1 }` to disable retries entirely.
|
|
949
1182
|
*/
|
|
950
1183
|
retryPolicy?: RetryPolicy;
|
|
1184
|
+
/**
|
|
1185
|
+
* Base URL for the trust-root host (default: https://keys.atlasent.io/.well-known).
|
|
1186
|
+
* Override for air-gapped / enterprise mirror deployments.
|
|
1187
|
+
* Per ADR-005 D2.
|
|
1188
|
+
*/
|
|
1189
|
+
trustRootUrl?: string;
|
|
1190
|
+
/**
|
|
1191
|
+
* Trust-root snapshot refresh interval in milliseconds.
|
|
1192
|
+
* Default: 4 hours. Floor: 5 minutes (ADR-005 D2).
|
|
1193
|
+
* Set to 0 to inherit the default.
|
|
1194
|
+
*/
|
|
1195
|
+
trustSnapshotRefreshMs?: number;
|
|
951
1196
|
}
|
|
952
1197
|
/** Permit lifecycle status. */
|
|
953
1198
|
type PermitStatus = "issued" | "verified" | "consumed" | "expired" | "revoked";
|
|
954
1199
|
/**
|
|
955
1200
|
* Wire shape of a Permit row, returned by {@link AtlaSentClient.getPermit}
|
|
956
|
-
* and {@link AtlaSentClient.listPermits}.
|
|
957
|
-
* schema.
|
|
958
|
-
*
|
|
959
|
-
* Revocation fields (`revoked_at`, `revoked_by`, `revoke_reason`) are
|
|
960
|
-
* populated only when `status === 'revoked'`; null otherwise.
|
|
1201
|
+
* and {@link AtlaSentClient.listPermits}.
|
|
961
1202
|
*/
|
|
962
1203
|
interface PermitRecord {
|
|
963
1204
|
id: string;
|
|
@@ -976,27 +1217,23 @@ interface PermitRecord {
|
|
|
976
1217
|
signature?: string;
|
|
977
1218
|
payload_hash?: string | null;
|
|
978
1219
|
decision_id?: string | null;
|
|
1220
|
+
/** SHA-256 hex of the CDO that produced this permit. P1 provisional. */
|
|
1221
|
+
cdo_hash?: string | null;
|
|
979
1222
|
}
|
|
980
1223
|
/** Optional filters for {@link AtlaSentClient.listPermits}. */
|
|
981
1224
|
interface ListPermitsRequest {
|
|
982
1225
|
status?: PermitStatus;
|
|
983
1226
|
actorId?: string;
|
|
984
1227
|
actionType?: string;
|
|
985
|
-
/** ISO-8601 lower bound on `created_at`. */
|
|
986
1228
|
from?: string;
|
|
987
|
-
/** ISO-8601 upper bound on `created_at`. */
|
|
988
1229
|
to?: string;
|
|
989
|
-
/** Page size. Server max is 500; default 50. */
|
|
990
1230
|
limit?: number;
|
|
991
|
-
/** Pass `nextCursor` from a prior response to page forward. */
|
|
992
1231
|
cursor?: string;
|
|
993
1232
|
}
|
|
994
1233
|
/** Response from {@link AtlaSentClient.listPermits}. */
|
|
995
1234
|
interface ListPermitsResponse {
|
|
996
1235
|
permits: PermitRecord[];
|
|
997
|
-
/** Total matching rows ignoring `limit`/`cursor`. */
|
|
998
1236
|
total: number;
|
|
999
|
-
/** Pass on next call as `cursor`. Absent when no more rows. */
|
|
1000
1237
|
nextCursor?: string;
|
|
1001
1238
|
rateLimit: RateLimitState | null;
|
|
1002
1239
|
}
|
|
@@ -1007,41 +1244,19 @@ interface GetPermitResponse {
|
|
|
1007
1244
|
}
|
|
1008
1245
|
/**
|
|
1009
1246
|
* Response from {@link AtlaSentClient.checkPermitValid}.
|
|
1010
|
-
*
|
|
1011
|
-
* Lightweight validity snapshot returned by
|
|
1012
|
-
* `GET /v1/permits/{permitId}/valid`. Designed for guard heartbeat
|
|
1013
|
-
* polling — returns only the fields needed to determine whether to
|
|
1014
|
-
* abort a running permit mid-execution (via {@link PermitRevoked}).
|
|
1015
1247
|
*/
|
|
1016
1248
|
interface PermitValidResponse {
|
|
1017
|
-
/** True iff the permit is currently valid (active). */
|
|
1018
1249
|
valid: boolean;
|
|
1019
|
-
/**
|
|
1020
|
-
* Current lifecycle status of the permit.
|
|
1021
|
-
* - `"active"` — permit is valid and in-flight.
|
|
1022
|
-
* - `"expired"` — TTL elapsed before revocation or consumption.
|
|
1023
|
-
* - `"revoked"` — administratively revoked (see `revocation_id`).
|
|
1024
|
-
* - `"consumed"` — single-use permit already consumed.
|
|
1025
|
-
*/
|
|
1026
1250
|
status: "active" | "expired" | "revoked" | "consumed";
|
|
1027
|
-
/** ISO-8601 timestamp when the permit was revoked. Populated only when `status === "revoked"`. */
|
|
1028
1251
|
revoked_at?: string;
|
|
1029
|
-
/** Opaque identifier of the revocation record. Populated only when `status === "revoked"`. */
|
|
1030
1252
|
revocation_id?: string;
|
|
1031
1253
|
}
|
|
1032
1254
|
/** Input for {@link AtlaSentClient.revokePermitById}. */
|
|
1033
1255
|
interface RevokePermitByIdInput {
|
|
1034
|
-
/** Operator-supplied free-text reason. Recorded on the permit row,
|
|
1035
|
-
* written to the audit trail, and surfaced (truncated) on later
|
|
1036
|
-
* verify responses. Optional but strongly encouraged. */
|
|
1037
1256
|
reason?: string;
|
|
1038
1257
|
}
|
|
1039
1258
|
/**
|
|
1040
1259
|
* Response from {@link AtlaSentClient.revokePermitById}.
|
|
1041
|
-
*
|
|
1042
|
-
* Returns the updated {@link PermitRecord} with `status === 'revoked'`
|
|
1043
|
-
* and the populated `revoked_at` / `revoked_by` / `revoke_reason`
|
|
1044
|
-
* fields.
|
|
1045
1260
|
*/
|
|
1046
1261
|
interface RevokePermitByIdResponse {
|
|
1047
1262
|
permit: PermitRecord;
|
|
@@ -1049,23 +1264,12 @@ interface RevokePermitByIdResponse {
|
|
|
1049
1264
|
}
|
|
1050
1265
|
/**
|
|
1051
1266
|
* Response from {@link AtlaSentClient.verifyPermitById}.
|
|
1052
|
-
*
|
|
1053
|
-
* Returns the canonical verification envelope (`valid`,
|
|
1054
|
-
* `verification_type`, `reason`, `verified_at`, `evidence`) plus the
|
|
1055
|
-
* legacy {@link PermitRecord} fields preserved at the top level for
|
|
1056
|
-
* backward compatibility. The envelope shape matches the unified
|
|
1057
|
-
* verify response in atlasent-api PR #352.
|
|
1058
1267
|
*/
|
|
1059
1268
|
interface VerifyPermitByIdResponse {
|
|
1060
|
-
/** `true` iff the permit verified — i.e. unconsumed, unexpired, and signature OK. */
|
|
1061
1269
|
valid: boolean;
|
|
1062
|
-
/** Always `'permit'` on this surface. */
|
|
1063
1270
|
verification_type: "permit";
|
|
1064
|
-
/** Operator-readable explanation when `valid` is `false`; `null` on success. */
|
|
1065
1271
|
reason: string | null;
|
|
1066
|
-
/** Server clock at the moment verification ran. */
|
|
1067
1272
|
verified_at: string;
|
|
1068
|
-
/** Type-specific evidence — same fields as the openapi PermitVerifyEvidence schema. */
|
|
1069
1273
|
evidence: {
|
|
1070
1274
|
permit_id: string;
|
|
1071
1275
|
status: PermitStatus;
|
|
@@ -1075,196 +1279,608 @@ interface VerifyPermitByIdResponse {
|
|
|
1075
1279
|
payload_hash?: string | null;
|
|
1076
1280
|
decision_id?: string | null;
|
|
1077
1281
|
};
|
|
1078
|
-
/** Legacy: full permit row preserved at the top level. */
|
|
1079
1282
|
permit: PermitRecord;
|
|
1080
1283
|
rateLimit: RateLimitState | null;
|
|
1081
1284
|
}
|
|
1082
1285
|
/** Input for {@link AtlaSentClient.revokePermit}. */
|
|
1083
1286
|
interface RevokePermitRequest {
|
|
1084
|
-
/** The permit ID returned by a prior evaluate() call. */
|
|
1085
1287
|
permitId: string;
|
|
1086
|
-
/** Optional human-readable reason stored in the audit log. */
|
|
1087
1288
|
reason?: string;
|
|
1088
1289
|
}
|
|
1089
1290
|
/**
|
|
1090
1291
|
* Result of {@link AtlaSentClient.revokePermit}.
|
|
1091
1292
|
*
|
|
1092
1293
|
* @deprecated Use {@link RevokePermitByIdResponse} via
|
|
1093
|
-
* {@link AtlaSentClient.revokePermitById}
|
|
1094
|
-
* (`POST /v1/permits/{id}/revoke`) returns the full updated
|
|
1095
|
-
* {@link PermitRecord} with `revoked_at`/`revoked_by`/`revoke_reason`
|
|
1096
|
-
* populated, instead of the legacy `{revoked, permitId}` envelope.
|
|
1294
|
+
* {@link AtlaSentClient.revokePermitById}.
|
|
1097
1295
|
* Will be removed in `@atlasent/sdk@3`.
|
|
1098
1296
|
*/
|
|
1099
1297
|
interface RevokePermitResponse {
|
|
1100
|
-
/** `true` when the permit was found and successfully revoked. */
|
|
1101
1298
|
revoked: boolean;
|
|
1102
|
-
/** Echo of the revoked permit's ID. */
|
|
1103
1299
|
permitId: string;
|
|
1104
|
-
/** ISO-8601 timestamp of when the revocation was recorded. `undefined` when not returned by the server. */
|
|
1105
1300
|
revokedAt?: string | undefined;
|
|
1106
|
-
/** Audit hash for the revocation event. `undefined` when not returned by the server. */
|
|
1107
1301
|
auditHash?: string | undefined;
|
|
1108
|
-
/** Per-key rate-limit state. `null` when the server didn't emit headers. */
|
|
1109
1302
|
rateLimit: RateLimitState | null;
|
|
1110
1303
|
}
|
|
1111
|
-
/**
|
|
1112
|
-
* One stage of a single policy's constraint evaluation.
|
|
1113
|
-
*
|
|
1114
|
-
* Mirrors `ConstraintTraceStage` in
|
|
1115
|
-
* `atlasent-api/packages/types/src/index.ts`. Emitted by the rule
|
|
1116
|
-
* engine when the request URL carries `?include=constraint_trace`.
|
|
1117
|
-
*
|
|
1118
|
-
* Forward-compat: extra engine-side keys are tolerated; readers
|
|
1119
|
-
* should not assume this is a closed shape.
|
|
1120
|
-
*/
|
|
1121
1304
|
interface ConstraintTraceStage {
|
|
1122
|
-
/** Engine stage name (e.g. `"role_check"`, `"context"`). */
|
|
1123
1305
|
readonly stage: string;
|
|
1124
|
-
/** Optional rule identifier; absent for wrapper stages. */
|
|
1125
1306
|
readonly rule?: string;
|
|
1126
|
-
/** True iff this stage's predicate fired. */
|
|
1127
1307
|
readonly matched: boolean;
|
|
1128
|
-
/** Optional human-readable note from the engine. */
|
|
1129
1308
|
readonly detail?: string;
|
|
1130
|
-
/** Zero-based position within the policy's `stages` array. */
|
|
1131
1309
|
readonly order: number;
|
|
1132
|
-
/** Forward-compat: tolerate unknown engine-side keys without crashing. */
|
|
1133
1310
|
readonly [key: string]: unknown;
|
|
1134
1311
|
}
|
|
1135
|
-
/**
|
|
1136
|
-
* Per-policy block of a constraint trace.
|
|
1137
|
-
*
|
|
1138
|
-
* Mirrors `ConstraintTracePolicy` in
|
|
1139
|
-
* `atlasent-api/packages/types/src/index.ts`. The handler iterates
|
|
1140
|
-
* active policies in order until first non-allow; the policy that
|
|
1141
|
-
* produced the outer decision has `decision !== "allow"`.
|
|
1142
|
-
*/
|
|
1143
1312
|
interface ConstraintTracePolicy {
|
|
1144
|
-
/** Stable identifier of the evaluated policy. */
|
|
1145
1313
|
readonly policy_id: string;
|
|
1146
|
-
/** Policy-level decision (`"allow"|"deny"|"hold"|"escalate"`). */
|
|
1147
1314
|
readonly decision: string;
|
|
1148
|
-
/** Engine-side fingerprint of the bundle row. */
|
|
1149
1315
|
readonly fingerprint: string;
|
|
1150
|
-
/**
|
|
1151
|
-
* Optional engine-computed risk score from a `risk` rule clause.
|
|
1152
|
-
* Distinct from the heuristic risk score on the outer envelope.
|
|
1153
|
-
*/
|
|
1154
1316
|
readonly risk_score?: number;
|
|
1155
|
-
/** Ordered stages produced while evaluating this policy. */
|
|
1156
1317
|
readonly stages: ReadonlyArray<ConstraintTraceStage>;
|
|
1157
|
-
/** Forward-compat: tolerate unknown engine-side keys. */
|
|
1158
1318
|
readonly [key: string]: unknown;
|
|
1159
1319
|
}
|
|
1160
|
-
/**
|
|
1161
|
-
* Top-level constraint trace returned by
|
|
1162
|
-
* `/v1-evaluate?include=constraint_trace`.
|
|
1163
|
-
*
|
|
1164
|
-
* Mirrors `ConstraintTraceResponse` in
|
|
1165
|
-
* `atlasent-api/packages/types/src/index.ts`. Present iff the
|
|
1166
|
-
* caller requested the trace; the SDK's preflight helper always
|
|
1167
|
-
* requests it.
|
|
1168
|
-
*/
|
|
1169
1320
|
interface ConstraintTrace {
|
|
1170
|
-
/** Per-policy blocks in evaluation order. */
|
|
1171
1321
|
readonly rules_evaluated: ReadonlyArray<ConstraintTracePolicy>;
|
|
1172
|
-
/**
|
|
1173
|
-
* Policy id whose evaluation produced the outer decision. Equals
|
|
1174
|
-
* the outer `matched_policy_id` on non-allow paths; `undefined` on
|
|
1175
|
-
* a clean allow (all policies passed).
|
|
1176
|
-
*/
|
|
1177
1322
|
readonly matching_policy_id?: string;
|
|
1178
|
-
/** Forward-compat: tolerate unknown engine-side keys. */
|
|
1179
1323
|
readonly [key: string]: unknown;
|
|
1180
1324
|
}
|
|
1181
|
-
/**
|
|
1182
|
-
* Result of {@link AtlaSentClient.evaluatePreflight}.
|
|
1183
|
-
*
|
|
1184
|
-
* Wraps the regular {@link EvaluateResponse} plus the
|
|
1185
|
-
* {@link ConstraintTrace} returned when the request URL carries
|
|
1186
|
-
* `?include=constraint_trace`. The whole point of preflight is to
|
|
1187
|
-
* surface which stages / policies WOULD fire BEFORE pushing the
|
|
1188
|
-
* request onto an approval queue, so workflows can reject trivially
|
|
1189
|
-
* defective requests at submission time and only forward viable
|
|
1190
|
-
* requests to a human reviewer.
|
|
1191
|
-
*
|
|
1192
|
-
* `constraintTrace` is `null` on responses from older atlasent-api
|
|
1193
|
-
* deployments that do not echo the trace — forward-compatible
|
|
1194
|
-
* degradation.
|
|
1195
|
-
*/
|
|
1196
1325
|
interface EvaluatePreflightResponse {
|
|
1197
|
-
/** The regular evaluate response (decision, permitId, ...). */
|
|
1198
1326
|
readonly evaluation: EvaluateResponse;
|
|
1199
|
-
/**
|
|
1200
|
-
* The constraint trace, or `null` when the server omitted it
|
|
1201
|
-
* (older atlasent-api version).
|
|
1202
|
-
*/
|
|
1203
1327
|
readonly constraintTrace: ConstraintTrace | null;
|
|
1204
1328
|
}
|
|
1205
|
-
/**
|
|
1206
|
-
* Options for {@link AtlaSentClient.protectStream}.
|
|
1207
|
-
*
|
|
1208
|
-
* All fields are optional; defaults are used when omitted.
|
|
1209
|
-
*/
|
|
1210
1329
|
interface StreamOptions {
|
|
1211
|
-
/**
|
|
1212
|
-
* Optional abort signal to cancel the stream from the caller side.
|
|
1213
|
-
*/
|
|
1214
1330
|
signal?: AbortSignal;
|
|
1215
|
-
/**
|
|
1216
|
-
* Per-event timeout in milliseconds: if no SSE event arrives within
|
|
1217
|
-
* this window the stream throws {@link StreamTimeoutError}.
|
|
1218
|
-
* Defaults to 30 000 ms (30 s). Pass `0` to disable.
|
|
1219
|
-
*/
|
|
1220
1331
|
timeoutMs?: number;
|
|
1221
|
-
/**
|
|
1222
|
-
* Maximum reconnection attempts on network drop before the stream
|
|
1223
|
-
* gives up and throws. Defaults to 3.
|
|
1224
|
-
*/
|
|
1225
1332
|
maxRetries?: number;
|
|
1226
1333
|
}
|
|
1227
|
-
/** A policy decision emitted mid-stream. */
|
|
1228
1334
|
interface StreamDecisionEvent {
|
|
1229
1335
|
type: "decision";
|
|
1230
|
-
/**
|
|
1231
|
-
* Policy decision — canonical 4-value lowercase vocabulary:
|
|
1232
|
-
* `"allow"`, `"deny"`, `"hold"`, or `"escalate"`.
|
|
1233
|
-
*
|
|
1234
|
-
* Previously emitted `"ALLOW"` / `"DENY"` (uppercase, 2-value);
|
|
1235
|
-
* now unified with `decision_canonical`.
|
|
1236
|
-
*
|
|
1237
|
-
* @deprecated Read `decision_canonical` instead for forward-compatible
|
|
1238
|
-
* branching. Both fields now carry the same value. Will be
|
|
1239
|
-
* removed/changed in `@atlasent/sdk@3`.
|
|
1240
|
-
*/
|
|
1241
1336
|
decision: Decision;
|
|
1242
|
-
/**
|
|
1243
|
-
* Canonical 4-value decision, byte-identical to the wire.
|
|
1244
|
-
* One of `"allow"`, `"deny"`, `"hold"`, `"escalate"`.
|
|
1245
|
-
*/
|
|
1246
1337
|
decision_canonical: DecisionCanonical;
|
|
1247
|
-
/** Opaque permit identifier for a final allow. Pass to verifyPermit. */
|
|
1248
1338
|
permitId: string;
|
|
1249
|
-
/** Human-readable explanation from the policy engine. */
|
|
1250
1339
|
reason: string;
|
|
1251
|
-
/** Audit hash bound to this decision. */
|
|
1252
1340
|
auditHash: string;
|
|
1253
|
-
/** ISO-8601 timestamp of the decision. */
|
|
1254
1341
|
timestamp: string;
|
|
1255
|
-
/** When true the stream will emit done and close after this event. */
|
|
1256
1342
|
isFinal: boolean;
|
|
1257
1343
|
}
|
|
1258
|
-
/** An intermediate progress hint emitted before the final decision. */
|
|
1259
1344
|
interface StreamProgressEvent {
|
|
1260
1345
|
type: "progress";
|
|
1261
|
-
/** Human-readable stage name (e.g. "policy_loading", "context_enrichment"). */
|
|
1262
1346
|
stage: string;
|
|
1263
|
-
/** Additional server-defined fields — forward-compat, do not rely on shape. */
|
|
1264
1347
|
[key: string]: unknown;
|
|
1265
1348
|
}
|
|
1266
|
-
/** Union of all events yielded by {@link AtlaSentClient.protectStream}. */
|
|
1267
1349
|
type StreamEvent = StreamDecisionEvent | StreamProgressEvent;
|
|
1350
|
+
interface BatchEvalItem {
|
|
1351
|
+
agent: string;
|
|
1352
|
+
action: string;
|
|
1353
|
+
context?: Record<string, unknown>;
|
|
1354
|
+
}
|
|
1355
|
+
interface EvaluateBatchResultItem {
|
|
1356
|
+
index: number;
|
|
1357
|
+
decision?: DecisionCanonical;
|
|
1358
|
+
decisionId?: string;
|
|
1359
|
+
permitToken?: string | null;
|
|
1360
|
+
reason?: string;
|
|
1361
|
+
auditHash?: string;
|
|
1362
|
+
timestamp?: string;
|
|
1363
|
+
error?: string;
|
|
1364
|
+
message?: string;
|
|
1365
|
+
}
|
|
1366
|
+
interface BatchEvalResponse {
|
|
1367
|
+
batchId: string;
|
|
1368
|
+
items: EvaluateBatchResultItem[];
|
|
1369
|
+
partial: boolean;
|
|
1370
|
+
replayed?: boolean;
|
|
1371
|
+
rateLimit: RateLimitState | null;
|
|
1372
|
+
}
|
|
1373
|
+
interface SubscribeDecisionsOptions {
|
|
1374
|
+
types?: string[];
|
|
1375
|
+
actorId?: string;
|
|
1376
|
+
lastEventId?: string;
|
|
1377
|
+
maxSeconds?: number;
|
|
1378
|
+
signal?: AbortSignal;
|
|
1379
|
+
}
|
|
1380
|
+
interface DecisionStreamEvent {
|
|
1381
|
+
id?: string;
|
|
1382
|
+
type: string;
|
|
1383
|
+
decision?: DecisionCanonical;
|
|
1384
|
+
actorId?: string;
|
|
1385
|
+
resourceType?: string;
|
|
1386
|
+
resourceId?: string;
|
|
1387
|
+
payload?: Record<string, unknown>;
|
|
1388
|
+
hash?: string;
|
|
1389
|
+
previousHash?: string;
|
|
1390
|
+
occurredAt?: string;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
/**
|
|
1394
|
+
* Override types — wire shapes for `/v1/overrides`.
|
|
1395
|
+
*
|
|
1396
|
+
* Overrides allow an authorized actor to bypass a deny decision for a
|
|
1397
|
+
* specific evaluation. They must be approved before they take effect
|
|
1398
|
+
* and can be revoked at any time.
|
|
1399
|
+
*
|
|
1400
|
+
* Mirrors `api/src/schemas/overrides.ts` in atlasent-control-plane.
|
|
1401
|
+
*/
|
|
1402
|
+
/**
|
|
1403
|
+
* Lifecycle status of an override request.
|
|
1404
|
+
*
|
|
1405
|
+
* - `pending` — created, waiting for approval
|
|
1406
|
+
* - `approved` — approved and active; the evaluation's deny is lifted
|
|
1407
|
+
* - `revoked` — manually revoked
|
|
1408
|
+
* - `expired` — TTL elapsed before revocation
|
|
1409
|
+
*/
|
|
1410
|
+
type OverrideStatus = "pending" | "approved" | "revoked" | "expired";
|
|
1411
|
+
/**
|
|
1412
|
+
* The event types that can appear on an override's event log.
|
|
1413
|
+
*/
|
|
1414
|
+
type OverrideEventType = "created" | "approved" | "revoked";
|
|
1415
|
+
/**
|
|
1416
|
+
* Canonical Override domain object returned by the API.
|
|
1417
|
+
*
|
|
1418
|
+
* All timestamps are ISO-8601 UTC strings. Nullable fields are `null`
|
|
1419
|
+
* rather than omitted so wire shapes are stable.
|
|
1420
|
+
*/
|
|
1421
|
+
interface OverrideV1 {
|
|
1422
|
+
id: string;
|
|
1423
|
+
orgId: string;
|
|
1424
|
+
/** The evaluation ID this override applies to. */
|
|
1425
|
+
evaluationId: string;
|
|
1426
|
+
/** Human-readable justification provided at creation time. */
|
|
1427
|
+
reason: string;
|
|
1428
|
+
status: OverrideStatus;
|
|
1429
|
+
/** Actor who requested the override. */
|
|
1430
|
+
requestedBy: string;
|
|
1431
|
+
/** Actor who approved the override, or `null` if not yet approved. */
|
|
1432
|
+
approvedBy: string | null;
|
|
1433
|
+
/** Actor who revoked the override, or `null` if not revoked. */
|
|
1434
|
+
revokedBy: string | null;
|
|
1435
|
+
/** ISO-8601 creation timestamp. */
|
|
1436
|
+
createdAt: string;
|
|
1437
|
+
/** ISO-8601 approval timestamp, or `null`. */
|
|
1438
|
+
approvedAt: string | null;
|
|
1439
|
+
/** ISO-8601 revocation timestamp, or `null`. */
|
|
1440
|
+
revokedAt: string | null;
|
|
1441
|
+
/** ISO-8601 expiry timestamp, or `null` if no TTL was set. */
|
|
1442
|
+
expiresAt: string | null;
|
|
1443
|
+
/** Arbitrary key/value metadata attached at creation. `null` when none. */
|
|
1444
|
+
metadata: Record<string, unknown> | null;
|
|
1445
|
+
}
|
|
1446
|
+
/**
|
|
1447
|
+
* Paginated list of overrides.
|
|
1448
|
+
*/
|
|
1449
|
+
interface OverrideListResponse {
|
|
1450
|
+
items: OverrideV1[];
|
|
1451
|
+
/** Opaque cursor for the next page. `null` when there are no more results. */
|
|
1452
|
+
nextCursor: string | null;
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
1455
|
+
* Input for `POST /v1/overrides` — request a new override.
|
|
1456
|
+
*/
|
|
1457
|
+
interface CreateOverrideRequest {
|
|
1458
|
+
/** Human-readable justification. Required; max 2000 characters. */
|
|
1459
|
+
reason: string;
|
|
1460
|
+
/** The evaluation ID to override. */
|
|
1461
|
+
evaluationId: string;
|
|
1462
|
+
/** Lifetime in seconds. Defaults to 3600. Max 604800 (7 days). */
|
|
1463
|
+
ttlSeconds?: number;
|
|
1464
|
+
/** Arbitrary metadata to attach to the override record. */
|
|
1465
|
+
metadata?: Record<string, unknown>;
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Audit event appended to an override's event log on every state mutation.
|
|
1469
|
+
*/
|
|
1470
|
+
interface OverrideEvent {
|
|
1471
|
+
id: string;
|
|
1472
|
+
overrideId: string;
|
|
1473
|
+
orgId: string;
|
|
1474
|
+
/** Actor who caused this event. */
|
|
1475
|
+
actorId: string;
|
|
1476
|
+
type: OverrideEventType;
|
|
1477
|
+
/** ISO-8601 timestamp. */
|
|
1478
|
+
at: string;
|
|
1479
|
+
/** Event-specific payload. `null` when none. */
|
|
1480
|
+
payload: Record<string, unknown> | null;
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Response for `GET /v1/overrides/:id/events`.
|
|
1484
|
+
*/
|
|
1485
|
+
interface OverrideEventsResponse {
|
|
1486
|
+
items: OverrideEvent[];
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
/**
|
|
1490
|
+
* Compliance evidence types — wire shapes for `v1-compliance-evidence`.
|
|
1491
|
+
*
|
|
1492
|
+
* Supports on-demand SOC 2 Type II control evidence collection. The
|
|
1493
|
+
* same run shape is used for ISO 27001, GDPR, and HIPAA; control IDs
|
|
1494
|
+
* differ per framework.
|
|
1495
|
+
*/
|
|
1496
|
+
type ComplianceFramework = "soc2" | "iso27001" | "gdpr" | "hipaa";
|
|
1497
|
+
type EvidenceControlStatus = "pass" | "gap" | "finding";
|
|
1498
|
+
type ComplianceRunStatus = "pending" | "running" | "completed" | "failed";
|
|
1499
|
+
/**
|
|
1500
|
+
* A single evaluated control within an evidence run.
|
|
1501
|
+
* `evidence` is a free-form object whose keys are framework-specific
|
|
1502
|
+
* metric names (e.g. `mfa_enforced_policies`, `audit_events_last_30d`).
|
|
1503
|
+
*/
|
|
1504
|
+
interface EvidenceControl {
|
|
1505
|
+
control_id: string;
|
|
1506
|
+
title: string;
|
|
1507
|
+
status: EvidenceControlStatus;
|
|
1508
|
+
evidence: Record<string, unknown>;
|
|
1509
|
+
}
|
|
1510
|
+
interface ComplianceEvidenceSummary {
|
|
1511
|
+
total: number;
|
|
1512
|
+
pass: number;
|
|
1513
|
+
gap: number;
|
|
1514
|
+
finding: number;
|
|
1515
|
+
}
|
|
1516
|
+
interface ComplianceEvidenceRun {
|
|
1517
|
+
id: string;
|
|
1518
|
+
org_id: string;
|
|
1519
|
+
framework: ComplianceFramework;
|
|
1520
|
+
period_start: string;
|
|
1521
|
+
period_end: string;
|
|
1522
|
+
status: ComplianceRunStatus;
|
|
1523
|
+
controls: EvidenceControl[];
|
|
1524
|
+
summary: ComplianceEvidenceSummary | null;
|
|
1525
|
+
applied_by: string | null;
|
|
1526
|
+
created_at: string;
|
|
1527
|
+
}
|
|
1528
|
+
interface TriggerEvidenceRunRequest {
|
|
1529
|
+
framework: ComplianceFramework;
|
|
1530
|
+
/** ISO 8601 date string; defaults to 30 days ago on the server. */
|
|
1531
|
+
period_start?: string;
|
|
1532
|
+
/** ISO 8601 date string; defaults to now on the server. */
|
|
1533
|
+
period_end?: string;
|
|
1534
|
+
}
|
|
1535
|
+
interface TriggerEvidenceRunResponse {
|
|
1536
|
+
run: ComplianceEvidenceRun;
|
|
1537
|
+
}
|
|
1538
|
+
interface ListEvidenceRunsResponse {
|
|
1539
|
+
runs: ComplianceEvidenceRun[];
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* SOC 2 control IDs evaluated by `v1-compliance-evidence`.
|
|
1543
|
+
*
|
|
1544
|
+
* | ID | Area |
|
|
1545
|
+
* |--------|------|
|
|
1546
|
+
* | CC6.1 | MFA enforcement |
|
|
1547
|
+
* | CC6.3 | Periodic access reviews |
|
|
1548
|
+
* | CC7.2 | Audit trail completeness |
|
|
1549
|
+
* | CC8.1 | Change management / HITL |
|
|
1550
|
+
* | CC3.2 | Policy violations |
|
|
1551
|
+
*/
|
|
1552
|
+
type SOC2ControlId = "CC6.1" | "CC6.3" | "CC7.2" | "CC8.1" | "CC3.2";
|
|
1553
|
+
/**
|
|
1554
|
+
* Returns `true` when every control in the run has `pass` or `gap`
|
|
1555
|
+
* status (no `finding`). A `gap` means a control is partially met;
|
|
1556
|
+
* a `finding` is a blocking deficiency that requires remediation.
|
|
1557
|
+
*/
|
|
1558
|
+
declare function evidenceRunPasses(run: ComplianceEvidenceRun): boolean;
|
|
1559
|
+
/**
|
|
1560
|
+
* Returns controls that do not have `pass` status, sorted so
|
|
1561
|
+
* `finding` controls appear before `gap` controls.
|
|
1562
|
+
*/
|
|
1563
|
+
declare function nonPassingControls(run: ComplianceEvidenceRun): EvidenceControl[];
|
|
1564
|
+
|
|
1565
|
+
/**
|
|
1566
|
+
* Evidence Engine — per-decision proof artifacts, "why" traces, and
|
|
1567
|
+
* compliance-ready bundles.
|
|
1568
|
+
*
|
|
1569
|
+
* Turn every AtlaSent decision into tamper-evident proof that buyers
|
|
1570
|
+
* can hand to auditors, compliance teams, and regulators.
|
|
1571
|
+
*
|
|
1572
|
+
* Primary entry points:
|
|
1573
|
+
*
|
|
1574
|
+
* 1. `buildWhyTrace(decision, reasons, constraintTrace)` — converts
|
|
1575
|
+
* the ConstraintTrace from `?include=constraint_trace` into a
|
|
1576
|
+
* structured human/machine-readable "why allowed / why denied" trace.
|
|
1577
|
+
*
|
|
1578
|
+
* 2. `buildDecisionReceiptPayload(args)` — assembles the canonical
|
|
1579
|
+
* signable payload for a per-decision receipt.
|
|
1580
|
+
*
|
|
1581
|
+
* 3. `signDecisionReceiptHmac(payload, secret)` — HMAC-SHA256 sign.
|
|
1582
|
+
*
|
|
1583
|
+
* 4. `verifyDecisionReceiptHmac(receipt, secret)` — offline verify.
|
|
1584
|
+
*
|
|
1585
|
+
* 5. `computeBundleHash(bundle)` — SHA-256 of an ActionEvidenceBundle.
|
|
1586
|
+
*
|
|
1587
|
+
* 6. `soc2ControlCoverageForDecision(opts)` — map a decision to SOC 2
|
|
1588
|
+
* control coverage.
|
|
1589
|
+
*
|
|
1590
|
+
* The {@link DecisionReceipt} is the category-defining artifact: a
|
|
1591
|
+
* self-contained, signed, human-readable proof that a specific action
|
|
1592
|
+
* was (or was not) authorized at a specific moment. Every enforcement
|
|
1593
|
+
* adapter produces one; every compliance bundle includes one.
|
|
1594
|
+
*/
|
|
1595
|
+
|
|
1596
|
+
/**
|
|
1597
|
+
* One evaluated stage within a policy, in the order the engine ran it.
|
|
1598
|
+
*/
|
|
1599
|
+
interface WhyStage {
|
|
1600
|
+
/** Engine stage name (e.g. `"role_check"`, `"context"`). */
|
|
1601
|
+
stage: string;
|
|
1602
|
+
/** Rule identifier, if the stage is rule-bound. */
|
|
1603
|
+
rule?: string;
|
|
1604
|
+
/** Whether this stage's predicate fired / matched. */
|
|
1605
|
+
matched: boolean;
|
|
1606
|
+
/** Non-obvious detail from the engine. */
|
|
1607
|
+
detail?: string;
|
|
1608
|
+
/**
|
|
1609
|
+
* Impact classification:
|
|
1610
|
+
* - `"terminal"` — this stage caused the outer decision.
|
|
1611
|
+
* - `"contributing"` — matched but was not the decisive stage.
|
|
1612
|
+
* - `"passing"` — did not match; execution continued.
|
|
1613
|
+
*/
|
|
1614
|
+
impact: "terminal" | "contributing" | "passing";
|
|
1615
|
+
}
|
|
1616
|
+
/** Per-policy evaluation block within a WhyTrace. */
|
|
1617
|
+
interface WhyPolicyEvaluation {
|
|
1618
|
+
policy_id: string;
|
|
1619
|
+
/** Policy-level decision. */
|
|
1620
|
+
decision: string;
|
|
1621
|
+
/** Engine-side fingerprint of the policy bundle row. */
|
|
1622
|
+
fingerprint: string;
|
|
1623
|
+
/** Optional risk score from a `risk` rule clause. */
|
|
1624
|
+
risk_score?: number;
|
|
1625
|
+
/** Stages evaluated for this policy, in order. */
|
|
1626
|
+
stages: WhyStage[];
|
|
1627
|
+
/** `true` iff this policy's decision drove the outer envelope decision. */
|
|
1628
|
+
was_decisive: boolean;
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* Structured "why allowed / why denied" trace.
|
|
1632
|
+
*
|
|
1633
|
+
* Produced by `buildWhyTrace()` from the `ConstraintTrace` returned
|
|
1634
|
+
* by `/v1-evaluate?include=constraint_trace`. Suitable for:
|
|
1635
|
+
*
|
|
1636
|
+
* - UI display ("Why was this denied?")
|
|
1637
|
+
* - Email / Slack notifications
|
|
1638
|
+
* - Compliance-bundle human-readable section
|
|
1639
|
+
* - Machine-readable policy audit by external verifiers
|
|
1640
|
+
*
|
|
1641
|
+
* `summary` is a one-sentence plain-English explanation.
|
|
1642
|
+
*/
|
|
1643
|
+
interface WhyTrace {
|
|
1644
|
+
decision: DecisionCanonical;
|
|
1645
|
+
/** One-sentence human-readable explanation. */
|
|
1646
|
+
summary: string;
|
|
1647
|
+
/** Policy whose decision drove the outer result. Absent on clean allow. */
|
|
1648
|
+
matched_policy_id?: string;
|
|
1649
|
+
/** Per-policy evaluation blocks in evaluation order. */
|
|
1650
|
+
policy_evaluations: WhyPolicyEvaluation[];
|
|
1651
|
+
/**
|
|
1652
|
+
* The single stage that caused the terminal outcome, extracted for
|
|
1653
|
+
* quick access. `undefined` on a clean allow (no blocking stage).
|
|
1654
|
+
*/
|
|
1655
|
+
terminal_stage?: WhyStage;
|
|
1656
|
+
/** Total stages evaluated across all policies. */
|
|
1657
|
+
total_stages_evaluated: number;
|
|
1658
|
+
}
|
|
1659
|
+
/** Signing algorithm tag on a {@link DecisionReceipt}. */
|
|
1660
|
+
type DecisionReceiptAlgorithm = "hmac-sha256" | "ed25519" | "none";
|
|
1661
|
+
/**
|
|
1662
|
+
* The canonical signed payload of a {@link DecisionReceipt}.
|
|
1663
|
+
*
|
|
1664
|
+
* Field order is load-bearing: HMAC and chain verifiers stringify
|
|
1665
|
+
* this object and must reproduce byte-identical output. Never reorder
|
|
1666
|
+
* the fields; add new optional fields at the end only.
|
|
1667
|
+
*/
|
|
1668
|
+
interface DecisionReceiptPayload {
|
|
1669
|
+
receipt_id: string;
|
|
1670
|
+
evaluation_id: string;
|
|
1671
|
+
org_id: string;
|
|
1672
|
+
decision: DecisionCanonical;
|
|
1673
|
+
action: string;
|
|
1674
|
+
actor: string;
|
|
1675
|
+
resource_type: string | null;
|
|
1676
|
+
resource_id: string | null;
|
|
1677
|
+
reasons: string[];
|
|
1678
|
+
/** One-sentence human-readable summary from the WhyTrace. */
|
|
1679
|
+
why_summary: string;
|
|
1680
|
+
/** Permit ID when the decision was `"allow"`. */
|
|
1681
|
+
permit_id: string | null;
|
|
1682
|
+
/** Permit verification hash when the decision was `"allow"`. */
|
|
1683
|
+
permit_hash: string | null;
|
|
1684
|
+
/** Hash-chained audit-trail entry from the evaluate response. */
|
|
1685
|
+
audit_hash: string;
|
|
1686
|
+
/** SHA-256 hex of canonical JSON of the evaluate context. */
|
|
1687
|
+
context_hash: string;
|
|
1688
|
+
/** ISO-8601 when this receipt was issued. */
|
|
1689
|
+
issued_at: string;
|
|
1690
|
+
/** ISO-8601 TTL, or `null` for non-expiring receipts. */
|
|
1691
|
+
expires_at: string | null;
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* A signed, tamper-evident record of a single AtlaSent authorization
|
|
1695
|
+
* decision. Self-contained: contains everything an auditor needs to
|
|
1696
|
+
* verify the decision without querying the API.
|
|
1697
|
+
*
|
|
1698
|
+
* **Signature semantics (HMAC-SHA256):**
|
|
1699
|
+
*
|
|
1700
|
+
* `HMAC-SHA256(secret,
|
|
1701
|
+
* receipt_id + "\\n" + issued_at + "\\n" + JSON.stringify(payload))`
|
|
1702
|
+
*
|
|
1703
|
+
* When `algorithm === "ed25519"`, `signature` is hex-encoded Ed25519
|
|
1704
|
+
* over the same input string encoded as UTF-8.
|
|
1705
|
+
*
|
|
1706
|
+
* Offline verification: `verifyDecisionReceiptHmac(receipt, secret)`.
|
|
1707
|
+
*
|
|
1708
|
+
* Callers MUST reject receipts where `algorithm === "none"` in any
|
|
1709
|
+
* context requiring tamper-evidence.
|
|
1710
|
+
*/
|
|
1711
|
+
interface DecisionReceipt {
|
|
1712
|
+
receipt_id: string;
|
|
1713
|
+
evaluation_id: string;
|
|
1714
|
+
org_id: string;
|
|
1715
|
+
decision: DecisionCanonical;
|
|
1716
|
+
action: string;
|
|
1717
|
+
actor: string;
|
|
1718
|
+
resource_type: string | null;
|
|
1719
|
+
resource_id: string | null;
|
|
1720
|
+
reasons: string[];
|
|
1721
|
+
/**
|
|
1722
|
+
* Full structured "why" trace. `null` when the evaluation was
|
|
1723
|
+
* performed without `?include=constraint_trace`.
|
|
1724
|
+
*/
|
|
1725
|
+
why_trace: WhyTrace | null;
|
|
1726
|
+
permit_id: string | null;
|
|
1727
|
+
permit_hash: string | null;
|
|
1728
|
+
audit_hash: string;
|
|
1729
|
+
/** SHA-256 hex of canonical JSON of the evaluate context. */
|
|
1730
|
+
context_hash: string;
|
|
1731
|
+
issued_at: string;
|
|
1732
|
+
expires_at: string | null;
|
|
1733
|
+
algorithm: DecisionReceiptAlgorithm;
|
|
1734
|
+
/**
|
|
1735
|
+
* Hex (HMAC-SHA256 or Ed25519) signature, or `null` when
|
|
1736
|
+
* `algorithm === "none"`.
|
|
1737
|
+
*/
|
|
1738
|
+
signature: string | null;
|
|
1739
|
+
/** Registry key ID that signed, when `algorithm !== "none"`. */
|
|
1740
|
+
signing_key_id: string | null;
|
|
1741
|
+
/**
|
|
1742
|
+
* Full payload that was signed. Pass to `verifyDecisionReceiptHmac`
|
|
1743
|
+
* or reconstruct independently for external verification.
|
|
1744
|
+
*/
|
|
1745
|
+
payload: DecisionReceiptPayload;
|
|
1746
|
+
}
|
|
1747
|
+
/** Coverage summary for one compliance control within a bundle. */
|
|
1748
|
+
interface ComplianceControlCoverage {
|
|
1749
|
+
framework: ComplianceFramework;
|
|
1750
|
+
control_id: string;
|
|
1751
|
+
title: string;
|
|
1752
|
+
/** `true` when this bundle provides sufficient evidence for the control. */
|
|
1753
|
+
covered: boolean;
|
|
1754
|
+
/** Evidence kinds present in the bundle that map to this control. */
|
|
1755
|
+
evidence_kinds: string[];
|
|
1756
|
+
}
|
|
1757
|
+
/**
|
|
1758
|
+
* A compliance-ready evidence bundle for a single protected action.
|
|
1759
|
+
*
|
|
1760
|
+
* Contains everything an auditor needs to verify the authorization
|
|
1761
|
+
* decision without querying the API:
|
|
1762
|
+
*
|
|
1763
|
+
* - The signed {@link DecisionReceipt}
|
|
1764
|
+
* - The "why" trace (why allowed / why denied)
|
|
1765
|
+
* - Audit events from the decision window
|
|
1766
|
+
* - Permit chain (when the decision was `"allow"`)
|
|
1767
|
+
* - Active overrides that influenced the decision
|
|
1768
|
+
* - Per-control SOC 2 / compliance coverage map
|
|
1769
|
+
*
|
|
1770
|
+
* `bundle_hash` is SHA-256 of `JSON.stringify(bundle)` with
|
|
1771
|
+
* `bundle_hash` omitted, computed by `computeBundleHash()`. Use it
|
|
1772
|
+
* to verify the bundle was not modified after assembly.
|
|
1773
|
+
*/
|
|
1774
|
+
interface ActionEvidenceBundle {
|
|
1775
|
+
/** Wire format version. */
|
|
1776
|
+
v: 1;
|
|
1777
|
+
bundle_id: string;
|
|
1778
|
+
evaluation_id: string;
|
|
1779
|
+
org_id: string;
|
|
1780
|
+
action: string;
|
|
1781
|
+
actor: string;
|
|
1782
|
+
decision: DecisionCanonical;
|
|
1783
|
+
receipt: DecisionReceipt;
|
|
1784
|
+
why_trace: WhyTrace | null;
|
|
1785
|
+
/** Audit events from the evaluation window related to this action. */
|
|
1786
|
+
audit_events: AuditEvent[];
|
|
1787
|
+
/** Permit chain when the decision was `"allow"`. */
|
|
1788
|
+
permit_chain: PermitRecord[];
|
|
1789
|
+
/** Active overrides that influenced the decision. */
|
|
1790
|
+
overrides: OverrideV1[];
|
|
1791
|
+
compliance_controls: ComplianceControlCoverage[];
|
|
1792
|
+
generated_at: string;
|
|
1793
|
+
/** SHA-256 hex of canonical JSON of this bundle (sans this field). */
|
|
1794
|
+
bundle_hash: string;
|
|
1795
|
+
}
|
|
1796
|
+
/**
|
|
1797
|
+
* Convert a raw `ConstraintTrace` (from `?include=constraint_trace`)
|
|
1798
|
+
* into a structured {@link WhyTrace} with a human-readable summary.
|
|
1799
|
+
*
|
|
1800
|
+
* Safe to call with `trace === null` — returns a minimal trace with
|
|
1801
|
+
* the decision and a generic summary derived from `reasons`.
|
|
1802
|
+
*
|
|
1803
|
+
* ```ts
|
|
1804
|
+
* import { buildWhyTrace } from "@atlasent/sdk";
|
|
1805
|
+
*
|
|
1806
|
+
* const preflight = await client.evaluatePreflight({ agent, action, context });
|
|
1807
|
+
* const why = buildWhyTrace(
|
|
1808
|
+
* preflight.evaluation.decision_canonical,
|
|
1809
|
+
* preflight.evaluation.reasons,
|
|
1810
|
+
* preflight.constraintTrace,
|
|
1811
|
+
* );
|
|
1812
|
+
* console.log(why.summary);
|
|
1813
|
+
* // "Denied at stage 'role_check': actor lacks deploy role"
|
|
1814
|
+
* ```
|
|
1815
|
+
*/
|
|
1816
|
+
declare function buildWhyTrace(decision: DecisionCanonical, reasons: readonly string[], trace: ConstraintTrace | null): WhyTrace;
|
|
1817
|
+
/**
|
|
1818
|
+
* Compute SHA-256 hex of the recursively key-sorted canonical JSON of
|
|
1819
|
+
* `context`. Used as `context_hash` on a `DecisionReceipt` so the
|
|
1820
|
+
* original evaluate context can be independently verified offline.
|
|
1821
|
+
*/
|
|
1822
|
+
declare function computeContextHash(context: Record<string, unknown>): Promise<string>;
|
|
1823
|
+
/**
|
|
1824
|
+
* Assemble a {@link DecisionReceiptPayload} — the canonical object
|
|
1825
|
+
* that is serialised and signed. Field insertion order is fixed;
|
|
1826
|
+
* do NOT reorder the fields below.
|
|
1827
|
+
*/
|
|
1828
|
+
declare function buildDecisionReceiptPayload(args: {
|
|
1829
|
+
receipt_id: string;
|
|
1830
|
+
evaluation_id: string;
|
|
1831
|
+
org_id: string;
|
|
1832
|
+
decision: DecisionCanonical;
|
|
1833
|
+
action: string;
|
|
1834
|
+
actor: string;
|
|
1835
|
+
resource_type?: string | null;
|
|
1836
|
+
resource_id?: string | null;
|
|
1837
|
+
reasons: readonly string[];
|
|
1838
|
+
why_summary: string;
|
|
1839
|
+
permit_id?: string | null;
|
|
1840
|
+
permit_hash?: string | null;
|
|
1841
|
+
audit_hash: string;
|
|
1842
|
+
context_hash: string;
|
|
1843
|
+
issued_at: string;
|
|
1844
|
+
expires_at?: string | null;
|
|
1845
|
+
}): DecisionReceiptPayload;
|
|
1846
|
+
/**
|
|
1847
|
+
* HMAC-SHA256 sign a {@link DecisionReceiptPayload}. Returns the
|
|
1848
|
+
* hex-encoded MAC. Store as `receipt.signature` with
|
|
1849
|
+
* `algorithm: "hmac-sha256"`.
|
|
1850
|
+
*
|
|
1851
|
+
* Uses `crypto.subtle` (browser / Node 20+ / Cloudflare) or falls
|
|
1852
|
+
* back to `node:crypto` on older Node runtimes.
|
|
1853
|
+
*/
|
|
1854
|
+
declare function signDecisionReceiptHmac(payload: DecisionReceiptPayload, secret: string): Promise<string>;
|
|
1855
|
+
/**
|
|
1856
|
+
* Verify an HMAC-SHA256-signed {@link DecisionReceipt} offline.
|
|
1857
|
+
* Returns `false` (does not throw) on any verification failure.
|
|
1858
|
+
*
|
|
1859
|
+
* Callers MUST reject receipts where `receipt.algorithm !== "hmac-sha256"`.
|
|
1860
|
+
*/
|
|
1861
|
+
declare function verifyDecisionReceiptHmac(receipt: DecisionReceipt, secret: string): Promise<boolean>;
|
|
1862
|
+
/**
|
|
1863
|
+
* Compute SHA-256 hex of `JSON.stringify(bundle)` with `bundle_hash`
|
|
1864
|
+
* omitted. Store as `bundle.bundle_hash` after assembly.
|
|
1865
|
+
*
|
|
1866
|
+
* An external verifier can reproduce this value independently to
|
|
1867
|
+
* confirm the bundle was not modified after export.
|
|
1868
|
+
*/
|
|
1869
|
+
declare function computeBundleHash(bundle: Omit<ActionEvidenceBundle, "bundle_hash">): Promise<string>;
|
|
1870
|
+
/**
|
|
1871
|
+
* Return the SOC 2 controls covered by a single authorization decision,
|
|
1872
|
+
* given what the bundle contains. Suitable for populating
|
|
1873
|
+
* `ActionEvidenceBundle.compliance_controls`.
|
|
1874
|
+
*
|
|
1875
|
+
* For ISO 27001 / GDPR / HIPAA coverage use the `@atlasent/evidence-bundle`
|
|
1876
|
+
* package's `buildEvidenceBundle()` which handles multi-framework mapping.
|
|
1877
|
+
*/
|
|
1878
|
+
declare function soc2ControlCoverageForDecision(opts: {
|
|
1879
|
+
decision: DecisionCanonical;
|
|
1880
|
+
hasPermitChain: boolean;
|
|
1881
|
+
hasAuditEvents: boolean;
|
|
1882
|
+
hasOverrides: boolean;
|
|
1883
|
+
}): ComplianceControlCoverage[];
|
|
1268
1884
|
|
|
1269
1885
|
/** Input to {@link protect}. Same shape as `EvaluateRequest`. */
|
|
1270
1886
|
interface ProtectRequest {
|
|
@@ -1287,6 +1903,8 @@ interface Permit {
|
|
|
1287
1903
|
reason: string;
|
|
1288
1904
|
/** ISO 8601 timestamp of the verification. */
|
|
1289
1905
|
timestamp: string;
|
|
1906
|
+
/** ISO-8601 expiration timestamp of the permit. null on pre-rollout servers. */
|
|
1907
|
+
permitExpiresAt: string | null;
|
|
1290
1908
|
}
|
|
1291
1909
|
/** Configuration for the process-wide singleton used by {@link protect}. */
|
|
1292
1910
|
interface ConfigureOptions {
|
|
@@ -1325,5 +1943,67 @@ declare function deployGate(request?: DeployGateRequest): Promise<DeployGateResp
|
|
|
1325
1943
|
* or server error. Same fail-closed contract: do not proceed.
|
|
1326
1944
|
*/
|
|
1327
1945
|
declare function protect(request: ProtectRequest): Promise<Permit>;
|
|
1946
|
+
/**
|
|
1947
|
+
* A verified {@link Permit} with an embedded signed {@link DecisionReceipt}.
|
|
1948
|
+
*
|
|
1949
|
+
* Returned by {@link protectWithEvidence}. Store `receipt` alongside
|
|
1950
|
+
* your action record (deploy logs, payment records, close workflows)
|
|
1951
|
+
* to give auditors a self-contained proof of authorization.
|
|
1952
|
+
*/
|
|
1953
|
+
interface PermitWithEvidence extends Permit {
|
|
1954
|
+
/** Signed per-decision receipt. `algorithm: "none"` when no signing secret was supplied. */
|
|
1955
|
+
receipt: DecisionReceipt;
|
|
1956
|
+
}
|
|
1957
|
+
/** Options for {@link protectWithEvidence}. */
|
|
1958
|
+
interface ProtectWithEvidenceOptions {
|
|
1959
|
+
/**
|
|
1960
|
+
* HMAC-SHA256 signing secret. When provided, the receipt is signed
|
|
1961
|
+
* and can be verified offline with `verifyDecisionReceiptHmac`.
|
|
1962
|
+
* Recommend `process.env.ATLASENT_RECEIPT_SIGNING_SECRET`.
|
|
1963
|
+
*/
|
|
1964
|
+
signingSecret?: string;
|
|
1965
|
+
/**
|
|
1966
|
+
* Registry key ID recorded on the receipt, paired with `signingSecret`.
|
|
1967
|
+
* Used for key rotation: store the ID alongside the receipt so
|
|
1968
|
+
* verifiers know which key to use.
|
|
1969
|
+
*/
|
|
1970
|
+
signingKeyId?: string;
|
|
1971
|
+
/**
|
|
1972
|
+
* If you have already called `client.evaluatePreflight()` for this
|
|
1973
|
+
* request, pass `constraintTrace` here to populate
|
|
1974
|
+
* `receipt.why_trace` with the full stage-by-stage "why" trace.
|
|
1975
|
+
* When omitted, `why_trace` is `null` on the receipt.
|
|
1976
|
+
*/
|
|
1977
|
+
constraintTrace?: ConstraintTrace | null;
|
|
1978
|
+
}
|
|
1979
|
+
/**
|
|
1980
|
+
* Authorize an action end-to-end and mint a signed {@link DecisionReceipt}.
|
|
1981
|
+
*
|
|
1982
|
+
* Same fail-closed contract as {@link protect} — throws
|
|
1983
|
+
* {@link AtlaSentDeniedError} on deny, {@link AtlaSentError} on
|
|
1984
|
+
* transport failure. The action MUST NOT proceed if this throws.
|
|
1985
|
+
*
|
|
1986
|
+
* On allow, returns the verified `Permit` plus a signed `DecisionReceipt`
|
|
1987
|
+
* that captures:
|
|
1988
|
+
* - The evaluation ID and decision
|
|
1989
|
+
* - Human-readable reasons
|
|
1990
|
+
* - Permit ID and hash
|
|
1991
|
+
* - Audit-trail hash (hash-chain link)
|
|
1992
|
+
* - SHA-256 of the evaluate context (tamper-evidence for the inputs)
|
|
1993
|
+
* - Optional "why" trace (pass `constraintTrace` from `evaluatePreflight`)
|
|
1994
|
+
*
|
|
1995
|
+
* ```ts
|
|
1996
|
+
* const { permit, receipt } = await protectWithEvidence(
|
|
1997
|
+
* { agent: "deploy-bot", action: "production.deploy", context },
|
|
1998
|
+
* {
|
|
1999
|
+
* signingSecret: process.env.ATLASENT_RECEIPT_SIGNING_SECRET,
|
|
2000
|
+
* signingKeyId: "key-v1",
|
|
2001
|
+
* },
|
|
2002
|
+
* );
|
|
2003
|
+
* // Store alongside the deployment record.
|
|
2004
|
+
* await db.deployments.create({ commitSha, permit, receipt });
|
|
2005
|
+
* ```
|
|
2006
|
+
*/
|
|
2007
|
+
declare function protectWithEvidence(request: ProtectRequest, opts?: ProtectWithEvidenceOptions): Promise<PermitWithEvidence>;
|
|
1328
2008
|
|
|
1329
|
-
export {
|
|
2009
|
+
export { BundleVerificationError as $, AtlaSentDeniedError as A, type BatchEvalItem as B, type ComplianceEvidenceRun as C, type DecisionCanonical as D, type EvaluateRequest as E, protect as F, type GetPermitResponse as G, deployGate as H, configure as I, type ActionEvidenceBundle as J, type AtlaSentDecision as K, type ListPermitsRequest as L, type AtlaSentDeniedErrorInit as M, type AtlaSentErrorCode as N, type OverrideV1 as O, type Permit as P, type AtlaSentErrorInit as Q, type RateLimitState as R, type SubscribeDecisionsOptions as S, AtlaSentEscalateError as T, type AtlaSentEscalateErrorInit as U, type VerifyPermitRequest as V, type AuditDecision as W, type AuditEvent as X, type AuditEventsPage as Y, type AuditExport as Z, type AuditExportSignatureStatus as _, AtlaSentError as a, protectWithEvidence as a$, type BvsSnapshot as a0, type CompletionProof as a1, type ComplianceControlCoverage as a2, type ComplianceEvidenceSummary as a3, type ComplianceFramework as a4, type ComplianceRunStatus as a5, type ConfigureOptions as a6, type ConsentClassProjection as a7, type ConstraintTrace as a8, type ConstraintTracePolicy as a9, type PermitRecord as aA, PermitRevoked as aB, type PermitStatus as aC, type PermitWithEvidence as aD, type ProtectWithEvidenceOptions as aE, type RetryPolicy as aF, type SOC2ControlId as aG, type StreamDecisionEvent as aH, StreamParseError as aI, type StreamProgressEvent as aJ, StreamTimeoutError as aK, type TriggerEvidenceRunRequest as aL, type TriggerEvidenceRunResponse as aM, type WhyPolicyEvaluation as aN, type WhyStage as aO, type WhyTrace as aP, buildDecisionReceiptPayload as aQ, buildWhyTrace as aR, computeBackoffMs as aS, computeBundleHash as aT, computeContextHash as aU, evidenceRunPasses as aV, hasAttemptsLeft as aW, isRetryable as aX, mergePolicy as aY, nonPassingControls as aZ, normalizePermitOutcome as a_, type ConstraintTraceStage as aa, type CreateOverrideRequest as ab, DEFAULT_RETRY_POLICY as ac, DEPLOYMENT_PRODUCTION_ACTION as ad, DEPLOY_GATE_CODES as ae, type Decision as af, type DecisionReceiptPayload as ag, type DeployGateContext as ah, type DeployGateDenyCode as ai, type DeployGateEvidence as aj, type DeployOverrideClaim as ak, type DeployPermitClaim as al, type EvaluateBatchResultItem as am, type EvaluateResponsePermit as an, type EvaluateRiskEnvelope as ao, type EvaluateRiskEnvelopeFactor as ap, type EvidenceControl as aq, type EvidenceControlStatus as ar, type ListEvidenceRunsResponse as as, type OverrideEvent as at, type OverrideEventType as au, type OverrideEventsResponse as av, type OverrideListResponse as aw, type OverrideStatus as ax, PRODUCTION_DEPLOY_ACTION as ay, type PermitOutcome as az, type ProtectRequest as b, signDecisionReceiptHmac as b0, soc2ControlCoverageForDecision as b1, verifyDecisionReceiptHmac as b2, type AtlaSentClientOptions as c, type EvaluateResponse as d, type BatchEvalResponse as e, type DecisionStreamEvent as f, type EvaluatePreflightResponse as g, type VerifyPermitResponse as h, type DeployGateRequest as i, type DeployGateResponse as j, type RevokePermitRequest as k, type RevokePermitResponse as l, type RevokePermitByIdInput as m, type RevokePermitByIdResponse as n, type VerifyPermitByIdResponse as o, type PermitValidResponse as p, type ListPermitsResponse as q, type ApiKeySelfResponse as r, type AuditEventsQuery as s, type AuditEventsResult as t, type AuditExportRequest as u, type AuditExportResult as v, type StreamOptions as w, type StreamEvent as x, type DecisionReceipt as y, type DecisionReceiptAlgorithm as z };
|