@empire-builder-kit/runtime 1.0.0-beta.9 → 1.0.0-rc.2
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/NOTICE +6 -0
- package/package.json +93 -3
- package/src/api-contract/artifacts.d.ts +67 -0
- package/src/api-contract/artifacts.js +349 -0
- package/src/api-contract/artifacts.js.map +1 -0
- package/src/api-contract/client.d.ts +79 -0
- package/src/api-contract/client.js +561 -0
- package/src/api-contract/client.js.map +1 -0
- package/src/api-contract/errors.d.ts +7 -0
- package/src/api-contract/errors.js +11 -0
- package/src/api-contract/errors.js.map +1 -0
- package/src/api-contract/index.d.ts +9 -0
- package/src/api-contract/index.js +10 -0
- package/src/api-contract/index.js.map +1 -0
- package/src/api-contract/operation.d.ts +118 -0
- package/src/api-contract/operation.js +609 -0
- package/src/api-contract/operation.js.map +1 -0
- package/src/api-contract/schema.d.ts +81 -0
- package/src/api-contract/schema.js +313 -0
- package/src/api-contract/schema.js.map +1 -0
- package/src/api-contract/server.d.ts +77 -0
- package/src/api-contract/server.js +466 -0
- package/src/api-contract/server.js.map +1 -0
- package/src/async-work/contract.d.ts +17 -0
- package/src/async-work/contract.js +105 -0
- package/src/async-work/contract.js.map +1 -0
- package/src/async-work/idempotency.d.ts +123 -0
- package/src/async-work/idempotency.js +167 -0
- package/src/async-work/idempotency.js.map +1 -0
- package/src/async-work/index.d.ts +8 -0
- package/src/async-work/index.js +9 -0
- package/src/async-work/index.js.map +1 -0
- package/src/async-work/provider.d.ts +90 -0
- package/src/async-work/provider.js +155 -0
- package/src/async-work/provider.js.map +1 -0
- package/src/async-work/recovery.d.ts +103 -0
- package/src/async-work/recovery.js +291 -0
- package/src/async-work/recovery.js.map +1 -0
- package/src/async-work/schedule.d.ts +117 -0
- package/src/async-work/schedule.js +279 -0
- package/src/async-work/schedule.js.map +1 -0
- package/src/async-work/sqs.d.ts +133 -0
- package/src/async-work/sqs.js +280 -0
- package/src/async-work/sqs.js.map +1 -0
- package/src/async-work/webhook.d.ts +60 -0
- package/src/async-work/webhook.js +178 -0
- package/src/async-work/webhook.js.map +1 -0
- package/src/async-work/workflow.d.ts +98 -0
- package/src/async-work/workflow.js +225 -0
- package/src/async-work/workflow.js.map +1 -0
- package/src/auth-backend.d.ts +12 -2
- package/src/auth-backend.js +30 -18
- package/src/auth-backend.js.map +1 -1
- package/src/authorization/admission.d.ts +30 -0
- package/src/authorization/admission.js +87 -0
- package/src/authorization/admission.js.map +1 -0
- package/src/authorization/approval.d.ts +99 -0
- package/src/authorization/approval.js +249 -0
- package/src/authorization/approval.js.map +1 -0
- package/src/authorization/audit.d.ts +35 -0
- package/src/authorization/audit.js +35 -0
- package/src/authorization/audit.js.map +1 -0
- package/src/authorization/delegation.d.ts +149 -0
- package/src/authorization/delegation.js +401 -0
- package/src/authorization/delegation.js.map +1 -0
- package/src/authorization/errors.d.ts +32 -0
- package/src/authorization/errors.js +153 -0
- package/src/authorization/errors.js.map +1 -0
- package/src/authorization/evaluator.d.ts +39 -0
- package/src/authorization/evaluator.js +199 -0
- package/src/authorization/evaluator.js.map +1 -0
- package/src/authorization/index.d.ts +14 -0
- package/src/authorization/index.js +15 -0
- package/src/authorization/index.js.map +1 -0
- package/src/authorization/machine-token.d.ts +87 -0
- package/src/authorization/machine-token.js +201 -0
- package/src/authorization/machine-token.js.map +1 -0
- package/src/authorization/machine.d.ts +32 -0
- package/src/authorization/machine.js +41 -0
- package/src/authorization/machine.js.map +1 -0
- package/src/authorization/model.d.ts +112 -0
- package/src/authorization/model.js +112 -0
- package/src/authorization/model.js.map +1 -0
- package/src/canonical-json.cjs +157 -0
- package/src/canonical-json.d.cts +26 -0
- package/src/canonical-json.d.ts +18 -0
- package/src/canonical-json.js +125 -0
- package/src/canonical-json.js.map +1 -0
- package/src/configuration/contract.d.ts +107 -0
- package/src/configuration/contract.js +461 -0
- package/src/configuration/contract.js.map +1 -0
- package/src/configuration/index.d.ts +3 -0
- package/src/configuration/index.js +4 -0
- package/src/configuration/index.js.map +1 -0
- package/src/configuration/provider.d.ts +59 -0
- package/src/configuration/provider.js +198 -0
- package/src/configuration/provider.js.map +1 -0
- package/src/configuration/rollout-evaluator.cjs +54 -0
- package/src/configuration/rollout-evaluator.d.cts +26 -0
- package/src/configuration/rollout-evaluator.d.ts +18 -0
- package/src/configuration/rollout-evaluator.js +38 -0
- package/src/configuration/rollout-evaluator.js.map +1 -0
- package/src/configuration/rollout-key.cjs +38 -0
- package/src/configuration/rollout-key.d.cts +14 -0
- package/src/configuration/rollout-key.d.ts +10 -0
- package/src/configuration/rollout-key.js +26 -0
- package/src/configuration/rollout-key.js.map +1 -0
- package/src/configuration/rollout.d.ts +60 -0
- package/src/configuration/rollout.js +42 -0
- package/src/configuration/rollout.js.map +1 -0
- package/src/data-lifecycle/contract.d.ts +33 -0
- package/src/data-lifecycle/contract.js +118 -0
- package/src/data-lifecycle/contract.js.map +1 -0
- package/src/data-lifecycle/event.d.ts +28 -0
- package/src/data-lifecycle/event.js +76 -0
- package/src/data-lifecycle/event.js.map +1 -0
- package/src/data-lifecycle/evidence.d.ts +65 -0
- package/src/data-lifecycle/evidence.js +162 -0
- package/src/data-lifecycle/evidence.js.map +1 -0
- package/src/data-lifecycle/holds.d.ts +29 -0
- package/src/data-lifecycle/holds.js +124 -0
- package/src/data-lifecycle/holds.js.map +1 -0
- package/src/data-lifecycle/index.d.ts +8 -0
- package/src/data-lifecycle/index.js +9 -0
- package/src/data-lifecycle/index.js.map +1 -0
- package/src/data-lifecycle/policy.d.ts +16 -0
- package/src/data-lifecycle/policy.js +79 -0
- package/src/data-lifecycle/policy.js.map +1 -0
- package/src/data-lifecycle/restore.d.ts +90 -0
- package/src/data-lifecycle/restore.js +336 -0
- package/src/data-lifecycle/restore.js.map +1 -0
- package/src/data-lifecycle/retention.d.ts +57 -0
- package/src/data-lifecycle/retention.js +232 -0
- package/src/data-lifecycle/retention.js.map +1 -0
- package/src/data-lifecycle/rights.d.ts +171 -0
- package/src/data-lifecycle/rights.js +533 -0
- package/src/data-lifecycle/rights.js.map +1 -0
- package/src/database.d.ts +36 -0
- package/src/database.js +119 -0
- package/src/database.js.map +1 -0
- package/src/deterministic-order.cjs +16 -0
- package/src/deterministic-order.d.cts +9 -0
- package/src/deterministic-order.d.ts +7 -0
- package/src/deterministic-order.js +10 -0
- package/src/deterministic-order.js.map +1 -0
- package/src/events.d.ts +28 -19
- package/src/events.js +171 -66
- package/src/events.js.map +1 -1
- package/src/index.d.ts +7 -1
- package/src/index.js +24 -0
- package/src/index.js.map +1 -1
- package/src/lambda.d.ts +8 -2
- package/src/lambda.js +100 -39
- package/src/lambda.js.map +1 -1
- package/src/logging.d.ts +95 -36
- package/src/logging.js +460 -62
- package/src/logging.js.map +1 -1
- package/src/observability.d.ts +80 -18
- package/src/observability.js +252 -61
- package/src/observability.js.map +1 -1
- package/src/performance/index.d.ts +1 -0
- package/src/performance/index.js +2 -0
- package/src/performance/index.js.map +1 -0
- package/src/performance/protected-load-endpoint.d.ts +140 -0
- package/src/performance/protected-load-endpoint.js +462 -0
- package/src/performance/protected-load-endpoint.js.map +1 -0
- package/src/rds-global-ca-bundle.d.ts +1 -0
- package/src/rds-global-ca-bundle.js +2742 -0
- package/src/rds-global-ca-bundle.js.map +1 -0
- package/src/reliability/burn.d.ts +39 -0
- package/src/reliability/burn.js +102 -0
- package/src/reliability/burn.js.map +1 -0
- package/src/reliability/contract.d.ts +5 -0
- package/src/reliability/contract.js +317 -0
- package/src/reliability/contract.js.map +1 -0
- package/src/reliability/incident.d.ts +16 -0
- package/src/reliability/incident.js +562 -0
- package/src/reliability/incident.js.map +1 -0
- package/src/reliability/index.d.ts +5 -0
- package/src/reliability/index.js +6 -0
- package/src/reliability/index.js.map +1 -0
- package/src/reliability/model.d.ts +191 -0
- package/src/reliability/model.fixtures.d.ts +2 -0
- package/src/reliability/model.fixtures.js +57 -0
- package/src/reliability/model.fixtures.js.map +1 -0
- package/src/reliability/model.js +2 -0
- package/src/reliability/model.js.map +1 -0
- package/src/reliability/slo.d.ts +9 -0
- package/src/reliability/slo.js +74 -0
- package/src/reliability/slo.js.map +1 -0
- package/src/request-context.d.ts +57 -15
- package/src/request-context.js +116 -36
- package/src/request-context.js.map +1 -1
- package/src/safe-reference.cjs +57 -0
- package/src/safe-reference.d.cts +25 -0
- package/src/safe-reference.d.ts +11 -0
- package/src/safe-reference.js +46 -0
- package/src/safe-reference.js.map +1 -0
- package/src/secrets/contract.d.ts +99 -0
- package/src/secrets/contract.js +238 -0
- package/src/secrets/contract.js.map +1 -0
- package/src/secrets/index.d.ts +4 -0
- package/src/secrets/index.js +5 -0
- package/src/secrets/index.js.map +1 -0
- package/src/secrets/observability.d.ts +14 -0
- package/src/secrets/observability.js +100 -0
- package/src/secrets/observability.js.map +1 -0
- package/src/secrets/personal.d.ts +48 -0
- package/src/secrets/personal.js +332 -0
- package/src/secrets/personal.js.map +1 -0
- package/src/secrets/resolver.d.ts +125 -0
- package/src/secrets/resolver.js +602 -0
- package/src/secrets/resolver.js.map +1 -0
- package/src/secrets/sensitive-patterns.cjs +84 -0
- package/src/secrets/sensitive-patterns.d.cts +62 -0
- package/src/secrets/sensitive-patterns.d.ts +40 -0
- package/src/secrets/sensitive-patterns.js +60 -0
- package/src/secrets/sensitive-patterns.js.map +1 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { canonicalJson } from '../canonical-json.js';
|
|
3
|
+
import { isBoundedSafeReference } from '../safe-reference.js';
|
|
4
|
+
import { allowAuthorization, denyAuthorization, } from './model.js';
|
|
5
|
+
export const APPROVAL_REQUEST_SCHEMA_VERSION = 1;
|
|
6
|
+
export const DEFAULT_MAX_APPROVAL_TTL_SECONDS = 24 * 60 * 60;
|
|
7
|
+
const SAFE_NAME = /^[a-z][a-z0-9-]{0,62}$/;
|
|
8
|
+
function requiredReference(value, label) {
|
|
9
|
+
const normalized = value.trim();
|
|
10
|
+
if (!isBoundedSafeReference(normalized)) {
|
|
11
|
+
throw new Error(`[runtime/authorization] Approval ${label} must be a bounded safe reference.`);
|
|
12
|
+
}
|
|
13
|
+
return normalized;
|
|
14
|
+
}
|
|
15
|
+
function instant(value, label) {
|
|
16
|
+
const parsed = Date.parse(value);
|
|
17
|
+
if (!Number.isFinite(parsed)) {
|
|
18
|
+
throw new Error(`[runtime/authorization] Approval ${label} must be a valid instant.`);
|
|
19
|
+
}
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Binds approval to the exact action, safe resource reference, and canonical
|
|
24
|
+
* command. The command itself is never retained on the approval record.
|
|
25
|
+
*/
|
|
26
|
+
export function digestApprovalRequest(input) {
|
|
27
|
+
const material = {
|
|
28
|
+
action: requiredReference(input.action, 'action'),
|
|
29
|
+
command: input.command,
|
|
30
|
+
resource: Object.assign(Object.assign({}, (input.resource.id
|
|
31
|
+
? { id: requiredReference(input.resource.id, 'resource id') }
|
|
32
|
+
: {})), { type: requiredReference(input.resource.type, 'resource type') }),
|
|
33
|
+
};
|
|
34
|
+
return createHash('sha256')
|
|
35
|
+
.update(canonicalJson(material, {
|
|
36
|
+
maximumKeyLength: 256,
|
|
37
|
+
rejectControlCharactersInKeys: true,
|
|
38
|
+
rejectEmptyKeys: true,
|
|
39
|
+
}), 'utf8')
|
|
40
|
+
.digest('hex');
|
|
41
|
+
}
|
|
42
|
+
export function toApprovalActorReference(principal) {
|
|
43
|
+
const effectiveHumanId = principal.authority.mode === 'delegated'
|
|
44
|
+
? principal.authority.delegatedBy.id
|
|
45
|
+
: principal.authority.mode === 'direct' && principal.actor.type === 'user'
|
|
46
|
+
? principal.actor.id
|
|
47
|
+
: undefined;
|
|
48
|
+
return Object.freeze(Object.assign(Object.assign({ actorId: requiredReference(principal.actor.id, 'actor id'), authorityMode: principal.authority.mode }, (effectiveHumanId
|
|
49
|
+
? {
|
|
50
|
+
effectiveHumanId: requiredReference(effectiveHumanId, 'effective human id'),
|
|
51
|
+
}
|
|
52
|
+
: {})), { subjectType: principal.actor.type }));
|
|
53
|
+
}
|
|
54
|
+
export function createApprovalRequest(input) {
|
|
55
|
+
if (!SAFE_NAME.test(input.slice)) {
|
|
56
|
+
throw new Error('[runtime/authorization] Approval Slice must be a safe name.');
|
|
57
|
+
}
|
|
58
|
+
const now = instant(input.now, 'requestedAt');
|
|
59
|
+
const expiresAt = instant(input.expiresAt, 'expiresAt');
|
|
60
|
+
if (expiresAt <= now ||
|
|
61
|
+
expiresAt - now > DEFAULT_MAX_APPROVAL_TTL_SECONDS * 1000) {
|
|
62
|
+
throw new Error(`[runtime/authorization] Approval lifetime must be positive and no longer than ${DEFAULT_MAX_APPROVAL_TTL_SECONDS} seconds.`);
|
|
63
|
+
}
|
|
64
|
+
return Object.freeze({
|
|
65
|
+
action: requiredReference(input.action, 'action'),
|
|
66
|
+
author: toApprovalActorReference(input.author),
|
|
67
|
+
expiresAt: new Date(expiresAt).toISOString(),
|
|
68
|
+
id: randomUUID(),
|
|
69
|
+
policyVersion: requiredReference(input.policyVersion, 'policy version'),
|
|
70
|
+
requestDigest: digestApprovalRequest(input),
|
|
71
|
+
requestedAt: new Date(now).toISOString(),
|
|
72
|
+
resource: Object.freeze(Object.assign(Object.assign({}, (input.resource.id
|
|
73
|
+
? { id: requiredReference(input.resource.id, 'resource id') }
|
|
74
|
+
: {})), { type: requiredReference(input.resource.type, 'resource type') })),
|
|
75
|
+
revision: 0,
|
|
76
|
+
schemaVersion: APPROVAL_REQUEST_SCHEMA_VERSION,
|
|
77
|
+
slice: input.slice,
|
|
78
|
+
status: 'pending',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function cloneRequest(request) {
|
|
82
|
+
return structuredClone(request);
|
|
83
|
+
}
|
|
84
|
+
export function expireApprovalRequest(request, now) {
|
|
85
|
+
const at = instant(now, 'expiry check');
|
|
86
|
+
if (['executed', 'executing', 'expired', 'rejected'].includes(request.status) ||
|
|
87
|
+
at < Date.parse(request.expiresAt)) {
|
|
88
|
+
return request;
|
|
89
|
+
}
|
|
90
|
+
return Object.freeze(Object.assign(Object.assign({}, cloneRequest(request)), { revision: request.revision + 1, status: 'expired' }));
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Enforces direct-human, non-author review. A human who authored through a
|
|
94
|
+
* delegated agent remains the effective author and cannot approve through a
|
|
95
|
+
* different session.
|
|
96
|
+
*/
|
|
97
|
+
export function decideApprovalRequest(request, input) {
|
|
98
|
+
const requiredPolicyVersion = requiredReference(input.requiredPolicyVersion, 'required policy version');
|
|
99
|
+
if (request.policyVersion !== requiredPolicyVersion) {
|
|
100
|
+
return {
|
|
101
|
+
decision: denyAuthorization('policy-stale', requiredPolicyVersion),
|
|
102
|
+
request,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const expired = expireApprovalRequest(request, input.now);
|
|
106
|
+
if (expired.status === 'expired') {
|
|
107
|
+
return {
|
|
108
|
+
decision: denyAuthorization('approval-expired', request.policyVersion),
|
|
109
|
+
request: expired,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const approver = toApprovalActorReference(input.approver);
|
|
113
|
+
const decidedAt = instant(input.now, 'decision time');
|
|
114
|
+
const selfReview = approver.actorId === request.author.actorId ||
|
|
115
|
+
(approver.effectiveHumanId !== undefined &&
|
|
116
|
+
approver.effectiveHumanId === request.author.effectiveHumanId) ||
|
|
117
|
+
(approver.effectiveHumanId !== undefined &&
|
|
118
|
+
approver.effectiveHumanId === request.author.actorId) ||
|
|
119
|
+
(request.author.effectiveHumanId !== undefined &&
|
|
120
|
+
request.author.effectiveHumanId === approver.actorId);
|
|
121
|
+
if (request.status !== 'pending' ||
|
|
122
|
+
decidedAt < Date.parse(request.requestedAt) ||
|
|
123
|
+
input.expectedRequestDigest !== request.requestDigest ||
|
|
124
|
+
input.approver.authority.mode !== 'direct' ||
|
|
125
|
+
input.approver.actor.type !== 'user' ||
|
|
126
|
+
selfReview) {
|
|
127
|
+
return {
|
|
128
|
+
decision: denyAuthorization('approval-invalid', request.policyVersion),
|
|
129
|
+
request,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const outcome = input.outcome;
|
|
133
|
+
const next = Object.freeze(Object.assign(Object.assign({}, cloneRequest(request)), { decision: Object.freeze({
|
|
134
|
+
at: new Date(decidedAt).toISOString(),
|
|
135
|
+
decidedBy: approver,
|
|
136
|
+
outcome,
|
|
137
|
+
reasonReference: requiredReference(input.reasonReference, 'decision reason reference'),
|
|
138
|
+
}), revision: request.revision + 1, status: outcome }));
|
|
139
|
+
return {
|
|
140
|
+
decision: allowAuthorization(request.policyVersion),
|
|
141
|
+
request: next,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export function authorizeApprovalExecution(request, input) {
|
|
145
|
+
var _a, _b, _c;
|
|
146
|
+
const now = instant(input.now, 'execution check');
|
|
147
|
+
const requiredPolicyVersion = requiredReference(input.requiredPolicyVersion, 'required policy version');
|
|
148
|
+
if (request.policyVersion !== requiredPolicyVersion) {
|
|
149
|
+
return denyAuthorization('policy-stale', requiredPolicyVersion);
|
|
150
|
+
}
|
|
151
|
+
if (request.status === 'expired' || now >= Date.parse(request.expiresAt)) {
|
|
152
|
+
return denyAuthorization('approval-expired', request.policyVersion);
|
|
153
|
+
}
|
|
154
|
+
if (digestApprovalRequest(input) !== request.requestDigest) {
|
|
155
|
+
return denyAuthorization('approval-invalid', request.policyVersion);
|
|
156
|
+
}
|
|
157
|
+
if (request.status === 'pending') {
|
|
158
|
+
return denyAuthorization('approval-pending', request.policyVersion);
|
|
159
|
+
}
|
|
160
|
+
const approver = (_a = request.decision) === null || _a === void 0 ? void 0 : _a.decidedBy;
|
|
161
|
+
const selfReview = (approver === null || approver === void 0 ? void 0 : approver.actorId) === request.author.actorId ||
|
|
162
|
+
((approver === null || approver === void 0 ? void 0 : approver.effectiveHumanId) !== undefined &&
|
|
163
|
+
approver.effectiveHumanId === request.author.effectiveHumanId) ||
|
|
164
|
+
((approver === null || approver === void 0 ? void 0 : approver.effectiveHumanId) !== undefined &&
|
|
165
|
+
approver.effectiveHumanId === request.author.actorId) ||
|
|
166
|
+
(request.author.effectiveHumanId !== undefined &&
|
|
167
|
+
request.author.effectiveHumanId === (approver === null || approver === void 0 ? void 0 : approver.actorId));
|
|
168
|
+
if (((_b = request.decision) === null || _b === void 0 ? void 0 : _b.outcome) !== 'approved' ||
|
|
169
|
+
(approver === null || approver === void 0 ? void 0 : approver.authorityMode) !== 'direct' ||
|
|
170
|
+
approver.subjectType !== 'user' ||
|
|
171
|
+
selfReview) {
|
|
172
|
+
return denyAuthorization('approval-invalid', request.policyVersion);
|
|
173
|
+
}
|
|
174
|
+
const decisionAt = (_c = request.decision) === null || _c === void 0 ? void 0 : _c.at;
|
|
175
|
+
if (now < Date.parse(request.requestedAt) ||
|
|
176
|
+
(decisionAt !== undefined && now < Date.parse(decisionAt))) {
|
|
177
|
+
return denyAuthorization('approval-invalid', request.policyVersion);
|
|
178
|
+
}
|
|
179
|
+
if (request.status !== 'approved') {
|
|
180
|
+
return denyAuthorization('approval-invalid', request.policyVersion);
|
|
181
|
+
}
|
|
182
|
+
return allowAuthorization(request.policyVersion);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Claims an approved command before its protected effect. Persist this
|
|
186
|
+
* revision with compare-and-set, then execute idempotently under executionId.
|
|
187
|
+
*/
|
|
188
|
+
export function beginApprovalExecution(request, input) {
|
|
189
|
+
var _a, _b;
|
|
190
|
+
const startedAt = instant(input.now, 'execution start');
|
|
191
|
+
const requiredPolicyVersion = requiredReference(input.requiredPolicyVersion, 'required policy version');
|
|
192
|
+
if (request.policyVersion !== requiredPolicyVersion) {
|
|
193
|
+
return {
|
|
194
|
+
decision: denyAuthorization('policy-stale', requiredPolicyVersion),
|
|
195
|
+
request,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (request.status === 'executing') {
|
|
199
|
+
const executionId = input.executionId === undefined
|
|
200
|
+
? undefined
|
|
201
|
+
: requiredReference(input.executionId, 'execution id');
|
|
202
|
+
const exactRetry = executionId !== undefined &&
|
|
203
|
+
((_a = request.execution) === null || _a === void 0 ? void 0 : _a.executionId) === executionId &&
|
|
204
|
+
digestApprovalRequest(input) === request.requestDigest &&
|
|
205
|
+
startedAt >= Date.parse(request.execution.startedAt) &&
|
|
206
|
+
Date.parse(request.execution.startedAt) < Date.parse(request.expiresAt);
|
|
207
|
+
return {
|
|
208
|
+
decision: exactRetry
|
|
209
|
+
? allowAuthorization(request.policyVersion)
|
|
210
|
+
: denyAuthorization('approval-invalid', request.policyVersion),
|
|
211
|
+
request,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const decision = authorizeApprovalExecution(request, input);
|
|
215
|
+
if (decision.decision === 'deny')
|
|
216
|
+
return { decision, request };
|
|
217
|
+
const executionId = requiredReference((_b = input.executionId) !== null && _b !== void 0 ? _b : randomUUID(), 'execution id');
|
|
218
|
+
return {
|
|
219
|
+
decision,
|
|
220
|
+
request: Object.freeze(Object.assign(Object.assign({}, cloneRequest(request)), { execution: Object.freeze({
|
|
221
|
+
executionId,
|
|
222
|
+
startedAt: new Date(startedAt).toISOString(),
|
|
223
|
+
}), revision: request.revision + 1, status: 'executing' })),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
export function completeApprovalExecution(request, input) {
|
|
227
|
+
var _a;
|
|
228
|
+
const completedAt = instant(input.now, 'execution completion');
|
|
229
|
+
const requiredPolicyVersion = requiredReference(input.requiredPolicyVersion, 'required policy version');
|
|
230
|
+
if (request.policyVersion !== requiredPolicyVersion) {
|
|
231
|
+
return {
|
|
232
|
+
decision: denyAuthorization('policy-stale', requiredPolicyVersion),
|
|
233
|
+
request,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
if (request.status !== 'executing' ||
|
|
237
|
+
((_a = request.execution) === null || _a === void 0 ? void 0 : _a.executionId) !== input.executionId ||
|
|
238
|
+
completedAt < Date.parse(request.execution.startedAt)) {
|
|
239
|
+
return {
|
|
240
|
+
decision: denyAuthorization('approval-invalid', request.policyVersion),
|
|
241
|
+
request,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
decision: allowAuthorization(request.policyVersion),
|
|
246
|
+
request: Object.freeze(Object.assign(Object.assign({}, cloneRequest(request)), { execution: Object.freeze(Object.assign(Object.assign({}, request.execution), { completedAt: new Date(completedAt).toISOString() })), revision: request.revision + 1, status: 'executed' })),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/authorization/approval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AuthorizationDecision, AuthorizationDenialCategory, AuthorizationInput, AuthorizationObligation } from './model.js';
|
|
2
|
+
export interface AuthorizationAuditProjectionOptions {
|
|
3
|
+
approvalReference?: string;
|
|
4
|
+
correlationId: string;
|
|
5
|
+
delegationReference?: string;
|
|
6
|
+
pseudonymousSubjectId: string;
|
|
7
|
+
resourceReference?: string;
|
|
8
|
+
slice: string;
|
|
9
|
+
stage: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
}
|
|
12
|
+
export interface AuthorizationAuditRecord {
|
|
13
|
+
action: string;
|
|
14
|
+
approvalReference?: string;
|
|
15
|
+
authorityMode: 'delegated' | 'direct' | 'machine';
|
|
16
|
+
correlationId: string;
|
|
17
|
+
decision: 'allow' | 'deny';
|
|
18
|
+
delegationReference?: string;
|
|
19
|
+
policyVersion: string;
|
|
20
|
+
principalKind: 'admin' | 'agent' | 'customer';
|
|
21
|
+
pseudonymousSubjectId: string;
|
|
22
|
+
reasonCategory: 'authorized' | AuthorizationDenialCategory;
|
|
23
|
+
resourceReference?: string;
|
|
24
|
+
resourceType: string;
|
|
25
|
+
slice: string;
|
|
26
|
+
stage: string;
|
|
27
|
+
subjectType: 'service' | 'system' | 'user';
|
|
28
|
+
timestamp: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Projects only the fixed semantic fields accepted by the authorization
|
|
32
|
+
* proposal. It never copies resource attributes, context facts, token claims,
|
|
33
|
+
* roles, scopes, email, or raw policy input into audit output.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toAuthorizationAuditRecord<Input extends AuthorizationInput, Obligation extends AuthorizationObligation>(input: Input, decision: AuthorizationDecision<Obligation>, options: AuthorizationAuditProjectionOptions): AuthorizationAuditRecord;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { isBoundedSafeReference } from '../safe-reference.js';
|
|
2
|
+
const SAFE_NAME = /^[a-z][a-z0-9-]{0,62}$/;
|
|
3
|
+
function assertSafeReference(value, label) {
|
|
4
|
+
if (!isBoundedSafeReference(value)) {
|
|
5
|
+
throw new Error(`[runtime/authorization] ${label} must be a bounded safe reference.`);
|
|
6
|
+
}
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Projects only the fixed semantic fields accepted by the authorization
|
|
11
|
+
* proposal. It never copies resource attributes, context facts, token claims,
|
|
12
|
+
* roles, scopes, email, or raw policy input into audit output.
|
|
13
|
+
*/
|
|
14
|
+
export function toAuthorizationAuditRecord(input, decision, options) {
|
|
15
|
+
if (!Number.isFinite(Date.parse(options.timestamp))) {
|
|
16
|
+
throw new Error('[runtime/authorization] Audit timestamp must be an ISO-compatible instant.');
|
|
17
|
+
}
|
|
18
|
+
if (!SAFE_NAME.test(options.slice) || !SAFE_NAME.test(options.stage)) {
|
|
19
|
+
throw new Error('[runtime/authorization] Audit Slice and stage must be safe names.');
|
|
20
|
+
}
|
|
21
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ action: assertSafeReference(input.action, 'audit action') }, (options.approvalReference
|
|
22
|
+
? {
|
|
23
|
+
approvalReference: assertSafeReference(options.approvalReference, 'approval reference'),
|
|
24
|
+
}
|
|
25
|
+
: {})), { authorityMode: input.principal.authority.mode, correlationId: assertSafeReference(options.correlationId, 'correlation id'), decision: decision.decision }), (options.delegationReference
|
|
26
|
+
? {
|
|
27
|
+
delegationReference: assertSafeReference(options.delegationReference, 'delegation reference'),
|
|
28
|
+
}
|
|
29
|
+
: {})), { policyVersion: assertSafeReference(decision.policyVersion, 'policy version'), principalKind: input.principal.kind, pseudonymousSubjectId: assertSafeReference(options.pseudonymousSubjectId, 'pseudonymous subject id'), reasonCategory: decision.decision === 'allow' ? 'authorized' : decision.category }), (options.resourceReference
|
|
30
|
+
? {
|
|
31
|
+
resourceReference: assertSafeReference(options.resourceReference, 'resource reference'),
|
|
32
|
+
}
|
|
33
|
+
: {})), { resourceType: assertSafeReference(input.resource.type, 'audit resource type'), slice: options.slice, stage: options.stage, subjectType: input.principal.actor.type, timestamp: options.timestamp });
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/authorization/audit.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAgC9D,MAAM,SAAS,GAAG,wBAAwB,CAAC;AAE3C,SAAS,mBAAmB,CAAC,KAAa,EAAE,KAAa;IACvD,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,oCAAoC,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAIxC,KAAY,EACZ,QAA2C,EAC3C,OAA4C;IAE5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;IACJ,CAAC;IAED,6FACE,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,IACtD,CAAC,OAAO,CAAC,iBAAiB;QAC3B,CAAC,CAAC;YACE,iBAAiB,EAAE,mBAAmB,CACpC,OAAO,CAAC,iBAAiB,EACzB,oBAAoB,CACrB;SACF;QACH,CAAC,CAAC,EAAE,CAAC,KACP,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAC7C,aAAa,EAAE,mBAAmB,CAAC,OAAO,CAAC,aAAa,EAAE,gBAAgB,CAAC,EAC3E,QAAQ,EAAE,QAAQ,CAAC,QAAQ,KACxB,CAAC,OAAO,CAAC,mBAAmB;QAC7B,CAAC,CAAC;YACE,mBAAmB,EAAE,mBAAmB,CACtC,OAAO,CAAC,mBAAmB,EAC3B,sBAAsB,CACvB;SACF;QACH,CAAC,CAAC,EAAE,CAAC,KACP,aAAa,EAAE,mBAAmB,CAChC,QAAQ,CAAC,aAAa,EACtB,gBAAgB,CACjB,EACD,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,EACnC,qBAAqB,EAAE,mBAAmB,CACxC,OAAO,CAAC,qBAAqB,EAC7B,yBAAyB,CAC1B,EACD,cAAc,EACZ,QAAQ,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,KAC/D,CAAC,OAAO,CAAC,iBAAiB;QAC3B,CAAC,CAAC;YACE,iBAAiB,EAAE,mBAAmB,CACpC,OAAO,CAAC,iBAAiB,EACzB,oBAAoB,CACrB;SACF;QACH,CAAC,CAAC,EAAE,CAAC,KACP,YAAY,EAAE,mBAAmB,CAC/B,KAAK,CAAC,QAAQ,CAAC,IAAI,EACnB,qBAAqB,CACtB,EACD,KAAK,EAAE,OAAO,CAAC,KAAK,EACpB,KAAK,EAAE,OAAO,CAAC,KAAK,EACpB,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EACvC,SAAS,EAAE,OAAO,CAAC,SAAS,IAC5B;AACJ,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { RequestActor } from '../request-context.js';
|
|
2
|
+
import type { AuthorizationEvaluator } from './evaluator.js';
|
|
3
|
+
import { type AuthorizationContext, type AuthorizationDecision, type AuthorizationInput, type AuthorizationObligation, type AuthorizationPrincipal, type AuthorizationResource } from './model.js';
|
|
4
|
+
export declare const DELEGATION_GRANT_SCHEMA_VERSION: 1;
|
|
5
|
+
export declare const DEFAULT_MAX_DELEGATION_TTL_SECONDS: number;
|
|
6
|
+
export declare const MAX_DELEGATION_WRITE_ATTEMPTS = 4;
|
|
7
|
+
export interface ExactDelegationResourceBoundary {
|
|
8
|
+
kind: 'exact';
|
|
9
|
+
resourceIds: readonly string[];
|
|
10
|
+
resourceType: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ConstraintDelegationResourceBoundary {
|
|
13
|
+
constraintId: string;
|
|
14
|
+
kind: 'constraint';
|
|
15
|
+
resourceType: string;
|
|
16
|
+
}
|
|
17
|
+
export type DelegationResourceBoundary = ConstraintDelegationResourceBoundary | ExactDelegationResourceBoundary;
|
|
18
|
+
export interface DelegationRateLimit {
|
|
19
|
+
maximumUses: number;
|
|
20
|
+
windowSeconds: number;
|
|
21
|
+
}
|
|
22
|
+
export interface DelegationUsage {
|
|
23
|
+
lastUsedAt?: string;
|
|
24
|
+
rateWindowStartedAt?: string;
|
|
25
|
+
rateWindowUses: number;
|
|
26
|
+
totalUses: number;
|
|
27
|
+
}
|
|
28
|
+
export interface DelegationSubjectReference {
|
|
29
|
+
id: string;
|
|
30
|
+
type: RequestActor['type'];
|
|
31
|
+
}
|
|
32
|
+
export interface DelegationGrant<Action extends string = string> {
|
|
33
|
+
actions: readonly Action[];
|
|
34
|
+
agent: DelegationSubjectReference;
|
|
35
|
+
audience: string;
|
|
36
|
+
/**
|
|
37
|
+
* SHA-256 digest of the audience-bound opaque capability. Plaintext is
|
|
38
|
+
* returned once from issueDelegation and is never persisted in the grant.
|
|
39
|
+
*/
|
|
40
|
+
capabilityDigest: string;
|
|
41
|
+
capabilityScopes: readonly string[];
|
|
42
|
+
delegator: DelegationSubjectReference & {
|
|
43
|
+
type: 'user';
|
|
44
|
+
};
|
|
45
|
+
expiresAt: string;
|
|
46
|
+
id: string;
|
|
47
|
+
issuedAt: string;
|
|
48
|
+
issuedUnderPolicyVersion: string;
|
|
49
|
+
maxUses?: number;
|
|
50
|
+
nonDelegableApprovalActions: readonly Action[];
|
|
51
|
+
purposeReference: string;
|
|
52
|
+
rateLimit?: DelegationRateLimit;
|
|
53
|
+
resourceBoundary: DelegationResourceBoundary;
|
|
54
|
+
revision: number;
|
|
55
|
+
revokedAt?: string;
|
|
56
|
+
revokedBy?: DelegationSubjectReference;
|
|
57
|
+
schemaVersion: typeof DELEGATION_GRANT_SCHEMA_VERSION;
|
|
58
|
+
slice: string;
|
|
59
|
+
status: 'active' | 'expired' | 'revoked';
|
|
60
|
+
usage: DelegationUsage;
|
|
61
|
+
}
|
|
62
|
+
export interface DelegationStore<Action extends string = string> {
|
|
63
|
+
/**
|
|
64
|
+
* Must create only when the id does not already exist.
|
|
65
|
+
*/
|
|
66
|
+
create(grant: DelegationGrant<Action>): boolean | Promise<boolean>;
|
|
67
|
+
read(delegationId: string): DelegationGrant<Action> | undefined | Promise<DelegationGrant<Action> | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* Must atomically compare revision and replace. Returning false forces the
|
|
70
|
+
* caller to re-read and revalidate revocation, expiry, and rate state.
|
|
71
|
+
*/
|
|
72
|
+
write(delegationId: string, expectedRevision: number, grant: DelegationGrant<Action>): boolean | Promise<boolean>;
|
|
73
|
+
}
|
|
74
|
+
export interface IssueDelegationInput<Action extends string = string> {
|
|
75
|
+
actions: readonly Action[];
|
|
76
|
+
agent: AuthorizationPrincipal;
|
|
77
|
+
audience: string;
|
|
78
|
+
capabilityScopes?: readonly string[];
|
|
79
|
+
delegator: AuthorizationPrincipal;
|
|
80
|
+
expiresAt: string;
|
|
81
|
+
issuedUnderPolicyVersion: string;
|
|
82
|
+
maxUses?: number;
|
|
83
|
+
nonDelegableApprovalActions?: readonly Action[];
|
|
84
|
+
now: string;
|
|
85
|
+
purposeReference: string;
|
|
86
|
+
rateLimit?: DelegationRateLimit;
|
|
87
|
+
resourceBoundary: DelegationResourceBoundary;
|
|
88
|
+
slice: string;
|
|
89
|
+
}
|
|
90
|
+
export interface IssuedDelegation<Action extends string = string> {
|
|
91
|
+
/**
|
|
92
|
+
* Opaque bearer capability returned once. It must be delivered only through
|
|
93
|
+
* an audience-bound server exchange and never logged or stored in plaintext.
|
|
94
|
+
*/
|
|
95
|
+
capability: string;
|
|
96
|
+
grant: DelegationGrant<Action>;
|
|
97
|
+
}
|
|
98
|
+
export interface DelegationUseResult<Action extends string, Obligation extends AuthorizationObligation> {
|
|
99
|
+
decision: AuthorizationDecision<Obligation>;
|
|
100
|
+
grant?: DelegationGrant<Action>;
|
|
101
|
+
/** Present only after online grant validation and the persisted use transition. */
|
|
102
|
+
principal?: AuthorizationPrincipal;
|
|
103
|
+
}
|
|
104
|
+
export interface UseDelegationInput<Action extends string, Resource extends AuthorizationResource, Context extends AuthorizationContext, Obligation extends AuthorizationObligation> {
|
|
105
|
+
action: Action;
|
|
106
|
+
agent: AuthorizationPrincipal;
|
|
107
|
+
audience: string;
|
|
108
|
+
capability: string;
|
|
109
|
+
context: Context;
|
|
110
|
+
delegationId: string;
|
|
111
|
+
evaluator: Pick<AuthorizationEvaluator<AuthorizationInput<Action, Resource, Context>, Obligation>, 'evaluate' | 'policyVersion'>;
|
|
112
|
+
matchesConstraint?: (constraintId: string, resource: Resource, context: Context) => boolean | Promise<boolean>;
|
|
113
|
+
/**
|
|
114
|
+
* Resolves the delegator's current direct authority from Slice-owned state.
|
|
115
|
+
* Delegated use fails closed when the subject cannot be resolved or no
|
|
116
|
+
* longer receives an allow decision for the requested action/resource.
|
|
117
|
+
*/
|
|
118
|
+
resolveDelegator(input: {
|
|
119
|
+
context: Context;
|
|
120
|
+
delegator: DelegationSubjectReference & {
|
|
121
|
+
type: 'user';
|
|
122
|
+
};
|
|
123
|
+
resource: Resource;
|
|
124
|
+
}): AuthorizationPrincipal | undefined | Promise<AuthorizationPrincipal | undefined>;
|
|
125
|
+
requiredCapabilityScopes?: readonly string[];
|
|
126
|
+
resource: Resource;
|
|
127
|
+
store: DelegationStore<Action>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Issues and persists an attended grant. The operation caller must already
|
|
131
|
+
* have authorized the grant-creation action; this function enforces the
|
|
132
|
+
* structural delegation invariants and never persists the opaque capability.
|
|
133
|
+
*/
|
|
134
|
+
export declare function issueDelegation<Action extends string>(store: DelegationStore<Action>, input: IssueDelegationInput<Action>): Promise<IssuedDelegation<Action>>;
|
|
135
|
+
/**
|
|
136
|
+
* Re-reads the grant online and persists a rate/use transition before
|
|
137
|
+
* returning allow. The store's compare-and-set is the concurrency boundary;
|
|
138
|
+
* the protected business effect must run only after this function allows.
|
|
139
|
+
*/
|
|
140
|
+
export declare function useDelegation<Action extends string, Resource extends AuthorizationResource, Context extends AuthorizationContext, Obligation extends AuthorizationObligation = AuthorizationObligation>(input: UseDelegationInput<Action, Resource, Context, Obligation>): Promise<DelegationUseResult<Action, Obligation>>;
|
|
141
|
+
export interface RevokeDelegationInput {
|
|
142
|
+
delegationId: string;
|
|
143
|
+
now: string;
|
|
144
|
+
revokedBy: AuthorizationPrincipal;
|
|
145
|
+
}
|
|
146
|
+
export declare function revokeDelegationGrant<Action extends string>(grant: DelegationGrant<Action>, input: Pick<RevokeDelegationInput, 'now' | 'revokedBy'>): DelegationGrant<Action>;
|
|
147
|
+
export declare function revokeDelegation<Action extends string>(store: DelegationStore<Action>, input: RevokeDelegationInput): Promise<DelegationGrant<Action> | undefined>;
|
|
148
|
+
export declare function expireDelegationGrant<Action extends string>(grant: DelegationGrant<Action>, now: string): DelegationGrant<Action>;
|
|
149
|
+
export declare function expireDelegation<Action extends string>(store: DelegationStore<Action>, delegationId: string, now: string): Promise<DelegationGrant<Action> | undefined>;
|