@stigmer/server 3.15.2 → 3.15.3-dev.20260914100347
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/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +103 -9
- package/dist/boot/compose.js.map +1 -1
- package/dist/domain/iampolicy/access-lists.d.ts +27 -0
- package/dist/domain/iampolicy/access-lists.d.ts.map +1 -0
- package/dist/domain/iampolicy/access-lists.js +124 -0
- package/dist/domain/iampolicy/access-lists.js.map +1 -0
- package/dist/domain/iampolicy/constants.d.ts +135 -0
- package/dist/domain/iampolicy/constants.d.ts.map +1 -0
- package/dist/domain/iampolicy/constants.js +203 -0
- package/dist/domain/iampolicy/constants.js.map +1 -0
- package/dist/domain/iampolicy/controller.d.ts +29 -0
- package/dist/domain/iampolicy/controller.d.ts.map +1 -0
- package/dist/domain/iampolicy/controller.js +451 -0
- package/dist/domain/iampolicy/controller.js.map +1 -0
- package/dist/domain/iampolicy/display-resolver.d.ts +6 -0
- package/dist/domain/iampolicy/display-resolver.d.ts.map +1 -0
- package/dist/domain/iampolicy/display-resolver.js +90 -0
- package/dist/domain/iampolicy/display-resolver.js.map +1 -0
- package/dist/domain/iampolicy/grant-path.d.ts +42 -0
- package/dist/domain/iampolicy/grant-path.d.ts.map +1 -0
- package/dist/domain/iampolicy/grant-path.js +183 -0
- package/dist/domain/iampolicy/grant-path.js.map +1 -0
- package/dist/domain/iampolicy/grant-scope.d.ts +4 -0
- package/dist/domain/iampolicy/grant-scope.d.ts.map +1 -0
- package/dist/domain/iampolicy/grant-scope.js +34 -0
- package/dist/domain/iampolicy/grant-scope.js.map +1 -0
- package/dist/domain/iampolicy/membership.d.ts +111 -0
- package/dist/domain/iampolicy/membership.d.ts.map +1 -0
- package/dist/domain/iampolicy/membership.js +152 -0
- package/dist/domain/iampolicy/membership.js.map +1 -0
- package/dist/domain/iampolicy/permissions.d.ts +19 -0
- package/dist/domain/iampolicy/permissions.d.ts.map +1 -0
- package/dist/domain/iampolicy/permissions.js +27 -0
- package/dist/domain/iampolicy/permissions.js.map +1 -0
- package/dist/domain/iampolicy/resource-store.d.ts +4 -0
- package/dist/domain/iampolicy/resource-store.d.ts.map +1 -0
- package/dist/domain/iampolicy/resource-store.js +135 -0
- package/dist/domain/iampolicy/resource-store.js.map +1 -0
- package/dist/domain/iampolicy/role-lifecycle.d.ts +9 -0
- package/dist/domain/iampolicy/role-lifecycle.d.ts.map +1 -0
- package/dist/domain/iampolicy/role-lifecycle.js +106 -0
- package/dist/domain/iampolicy/role-lifecycle.js.map +1 -0
- package/dist/domain/iampolicy/roles.d.ts +11 -0
- package/dist/domain/iampolicy/roles.d.ts.map +1 -0
- package/dist/domain/iampolicy/roles.js +78 -0
- package/dist/domain/iampolicy/roles.js.map +1 -0
- package/dist/domain/iampolicy/specs.d.ts +7 -0
- package/dist/domain/iampolicy/specs.d.ts.map +1 -0
- package/dist/domain/iampolicy/specs.js +45 -0
- package/dist/domain/iampolicy/specs.js.map +1 -0
- package/dist/domain/iampolicy/steps.d.ts +18 -0
- package/dist/domain/iampolicy/steps.d.ts.map +1 -0
- package/dist/domain/iampolicy/steps.js +117 -0
- package/dist/domain/iampolicy/steps.js.map +1 -0
- package/dist/domain/iampolicy/store-contract.d.ts +8 -0
- package/dist/domain/iampolicy/store-contract.d.ts.map +1 -0
- package/dist/domain/iampolicy/store-contract.js +258 -0
- package/dist/domain/iampolicy/store-contract.js.map +1 -0
- package/dist/domain/iampolicy/store.d.ts +78 -0
- package/dist/domain/iampolicy/store.d.ts.map +1 -0
- package/dist/domain/iampolicy/store.js +13 -0
- package/dist/domain/iampolicy/store.js.map +1 -0
- package/dist/domain/iampolicy/wire-refusals.d.ts +25 -0
- package/dist/domain/iampolicy/wire-refusals.d.ts.map +1 -0
- package/dist/domain/iampolicy/wire-refusals.js +76 -0
- package/dist/domain/iampolicy/wire-refusals.js.map +1 -0
- package/dist/domain/identityaccount/constants.d.ts +33 -0
- package/dist/domain/identityaccount/constants.d.ts.map +1 -1
- package/dist/domain/identityaccount/constants.js +2 -48
- package/dist/domain/identityaccount/constants.js.map +1 -1
- package/dist/domain/identityaccount/controller.d.ts +8 -1
- package/dist/domain/identityaccount/controller.d.ts.map +1 -1
- package/dist/domain/identityaccount/controller.js +54 -29
- package/dist/domain/identityaccount/controller.js.map +1 -1
- package/dist/domain/identityaccount/operator.d.ts.map +1 -1
- package/dist/domain/identityaccount/operator.js +2 -4
- package/dist/domain/identityaccount/operator.js.map +1 -1
- package/dist/domain/identityaccount/provisioning.d.ts +20 -1
- package/dist/domain/identityaccount/provisioning.d.ts.map +1 -1
- package/dist/domain/identityaccount/provisioning.js +17 -3
- package/dist/domain/identityaccount/provisioning.js.map +1 -1
- package/dist/domain/identityaccount/resolve.d.ts +23 -0
- package/dist/domain/identityaccount/resolve.d.ts.map +1 -1
- package/dist/domain/identityaccount/resolve.js +17 -0
- package/dist/domain/identityaccount/resolve.js.map +1 -1
- package/dist/domain/identityaccount/store-contract.d.ts +4 -18
- package/dist/domain/identityaccount/store-contract.d.ts.map +1 -1
- package/dist/domain/identityaccount/store-contract.js +12 -47
- package/dist/domain/identityaccount/store-contract.js.map +1 -1
- package/dist/extensions/authorization-queries.d.ts +81 -0
- package/dist/extensions/authorization-queries.d.ts.map +1 -0
- package/dist/extensions/authorization-queries.js +2 -0
- package/dist/extensions/authorization-queries.js.map +1 -0
- package/dist/extensions/drivers.d.ts +49 -2
- package/dist/extensions/drivers.d.ts.map +1 -1
- package/dist/extensions/identity.d.ts +14 -0
- package/dist/extensions/identity.d.ts.map +1 -1
- package/dist/extensions/identity.js +18 -1
- package/dist/extensions/identity.js.map +1 -1
- package/dist/extensions/policy-grant-scope.d.ts +50 -0
- package/dist/extensions/policy-grant-scope.d.ts.map +1 -0
- package/dist/extensions/policy-grant-scope.js +2 -0
- package/dist/extensions/policy-grant-scope.js.map +1 -0
- package/dist/extensions/registry.d.ts +23 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/extensions/registry.js +30 -0
- package/dist/extensions/registry.js.map +1 -1
- package/dist/extensions/resource-authorization.d.ts +63 -0
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/apiresource-meta.d.ts +56 -1
- package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
- package/dist/pipeline/apiresource-meta.js +155 -1
- package/dist/pipeline/apiresource-meta.js.map +1 -1
- package/dist/pipeline/interceptors/auth.d.ts +12 -0
- package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
- package/dist/pipeline/interceptors/auth.js +13 -1
- package/dist/pipeline/interceptors/auth.js.map +1 -1
- package/dist/pipeline/steps/authorize.d.ts +20 -5
- package/dist/pipeline/steps/authorize.d.ts.map +1 -1
- package/dist/pipeline/steps/authorize.js +37 -17
- package/dist/pipeline/steps/authorize.js.map +1 -1
- package/dist/pipeline/steps/defaults.d.ts +10 -0
- package/dist/pipeline/steps/defaults.d.ts.map +1 -1
- package/dist/pipeline/steps/defaults.js +39 -0
- package/dist/pipeline/steps/defaults.js.map +1 -1
- package/dist/store/port-contract.d.ts +61 -0
- package/dist/store/port-contract.d.ts.map +1 -0
- package/dist/store/port-contract.js +67 -0
- package/dist/store/port-contract.js.map +1 -0
- package/package.json +4 -4
- package/src/boot/compose.ts +107 -10
- package/src/domain/iampolicy/__tests__/access-lists.test.ts +238 -0
- package/src/domain/iampolicy/__tests__/constants.test.ts +388 -0
- package/src/domain/iampolicy/__tests__/controller.test.ts +960 -0
- package/src/domain/iampolicy/__tests__/display-resolver.test.ts +138 -0
- package/src/domain/iampolicy/__tests__/grant-path.test.ts +474 -0
- package/src/domain/iampolicy/__tests__/grant-scope.test.ts +61 -0
- package/src/domain/iampolicy/__tests__/iampolicy.test.ts +532 -0
- package/src/domain/iampolicy/__tests__/membership.test.ts +447 -0
- package/src/domain/iampolicy/__tests__/permissions.test.ts +41 -0
- package/src/domain/iampolicy/__tests__/resource-store.test.ts +165 -0
- package/src/domain/iampolicy/__tests__/role-lifecycle.test.ts +361 -0
- package/src/domain/iampolicy/__tests__/roles.test.ts +53 -0
- package/src/domain/iampolicy/__tests__/specs.test.ts +41 -0
- package/src/domain/iampolicy/__tests__/steps.test.ts +278 -0
- package/src/domain/iampolicy/__tests__/support.ts +195 -0
- package/src/domain/iampolicy/__tests__/wire-refusals.test.ts +117 -0
- package/src/domain/iampolicy/access-lists.ts +191 -0
- package/src/domain/iampolicy/constants.ts +243 -0
- package/src/domain/iampolicy/controller.ts +798 -0
- package/src/domain/iampolicy/display-resolver.ts +123 -0
- package/src/domain/iampolicy/grant-path.ts +270 -0
- package/src/domain/iampolicy/grant-scope.ts +36 -0
- package/src/domain/iampolicy/membership.ts +298 -0
- package/src/domain/iampolicy/permissions.ts +35 -0
- package/src/domain/iampolicy/resource-store.ts +186 -0
- package/src/domain/iampolicy/role-lifecycle.ts +132 -0
- package/src/domain/iampolicy/roles.ts +95 -0
- package/src/domain/iampolicy/specs.ts +53 -0
- package/src/domain/iampolicy/steps.ts +178 -0
- package/src/domain/iampolicy/store-contract.ts +450 -0
- package/src/domain/iampolicy/store.ts +103 -0
- package/src/domain/iampolicy/wire-refusals.ts +110 -0
- package/src/domain/identityaccount/__tests__/provisioning.test.ts +19 -7
- package/src/domain/identityaccount/__tests__/resolve.test.ts +113 -2
- package/src/domain/identityaccount/constants.ts +16 -31
- package/src/domain/identityaccount/controller.ts +65 -35
- package/src/domain/identityaccount/operator.ts +5 -5
- package/src/domain/identityaccount/provisioning.ts +43 -5
- package/src/domain/identityaccount/resolve.ts +43 -0
- package/src/domain/identityaccount/store-contract.ts +22 -70
- package/src/extensions/__tests__/composed-support.ts +87 -0
- package/src/extensions/__tests__/iam-policy-composed.test.ts +373 -0
- package/src/extensions/__tests__/iam-policy-points.test.ts +169 -0
- package/src/extensions/__tests__/identity-account-composed.test.ts +12 -78
- package/src/extensions/__tests__/identity.test.ts +62 -0
- package/src/extensions/__tests__/tier-truthfulness.test.ts +8 -0
- package/src/extensions/authorization-queries.ts +97 -0
- package/src/extensions/drivers.ts +49 -2
- package/src/extensions/identity.ts +21 -0
- package/src/extensions/policy-grant-scope.ts +50 -0
- package/src/extensions/registry.ts +62 -1
- package/src/extensions/resource-authorization.ts +65 -0
- package/src/index.ts +20 -0
- package/src/pipeline/__tests__/grantable-roles-for.test.ts +87 -0
- package/src/pipeline/__tests__/kind-by-enum-name.test.ts +107 -0
- package/src/pipeline/__tests__/kind-served-by-edition.test.ts +107 -0
- package/src/pipeline/apiresource-meta.ts +181 -1
- package/src/pipeline/interceptors/auth.ts +14 -1
- package/src/pipeline/steps/__tests__/authorize-annotation-completeness.test.ts +73 -3
- package/src/pipeline/steps/__tests__/authorize.test.ts +134 -9
- package/src/pipeline/steps/__tests__/derived-id.test.ts +49 -0
- package/src/pipeline/steps/authorize.ts +46 -21
- package/src/pipeline/steps/defaults.ts +42 -0
- package/src/store/__tests__/port-contract.test.ts +123 -0
- package/src/store/port-contract.ts +102 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The open-source IamPolicyStore: the port (store.ts) over the generic
|
|
3
|
+
* Store, rows of the `resources` table by kind (20260913.01, T01_0_plan.md
|
|
4
|
+
* §3a, §4). The composition root installs it when no extension registers
|
|
5
|
+
* `drivers.iamPolicyStore`.
|
|
6
|
+
*
|
|
7
|
+
* Reads. `findById` is a PRIMARY-KEY read. Every other find decodes
|
|
8
|
+
* `listResources(iam_policy)` and filters in memory: the `resources` table
|
|
9
|
+
* has no secondary index and `findByField` is single-hit, so a scan is the
|
|
10
|
+
* honest shape, and the row count is members × organizations on a
|
|
11
|
+
* self-host — measured in the entry's execution record (§4), not assumed.
|
|
12
|
+
* The filters are the cloud store's WHERE clauses restated over the proto
|
|
13
|
+
* (store.ts names each), so a driver's test over either edition reads the
|
|
14
|
+
* same contract.
|
|
15
|
+
*
|
|
16
|
+
* Writes. `save` refuses a policy whose id is not its triple's derived id
|
|
17
|
+
* (constants.ts policyIdFor): open source has no legacy random ids, and a
|
|
18
|
+
* stray id would break the primary key's promise of one row per triple.
|
|
19
|
+
* It is then read-then-write refusing a held id with DuplicatePolicyError,
|
|
20
|
+
* because the generic Store's saveResource is an upsert with no
|
|
21
|
+
* create-only form — the 2a adapter's shape and its recorded residual
|
|
22
|
+
* window (two concurrent saves of one triple may both fulfil; the primary
|
|
23
|
+
* key still guarantees ONE row, which is the invariant that matters, and
|
|
24
|
+
* the grant path treats a same-triple winner as the duplicate arm either
|
|
25
|
+
* way). Conditional store writes are a platform-wide follow-up, not this
|
|
26
|
+
* adapter's to invent.
|
|
27
|
+
*
|
|
28
|
+
* Store faults follow the ratified mapping (domain/apikey/lookup.ts): a
|
|
29
|
+
* typed ResourceNotFoundError reads as `undefined`; anything else
|
|
30
|
+
* propagates — an outage must never read as "no grant".
|
|
31
|
+
*
|
|
32
|
+
* The port's contract is proven by store-contract.ts, run over this
|
|
33
|
+
* adapter on both drivers in __tests__/resource-store.test.ts, which also
|
|
34
|
+
* pins the derived-id refusal that is this adapter's own.
|
|
35
|
+
*/
|
|
36
|
+
import { fromBinary } from "@bufbuild/protobuf";
|
|
37
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
38
|
+
import { IamPolicySchema } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/api_pb";
|
|
39
|
+
import { kindEnumName } from "../../pipeline/apiresource-meta.js";
|
|
40
|
+
import { ResourceNotFoundError } from "../../store/interface.js";
|
|
41
|
+
import { USER_GRANT_PRINCIPAL_KINDS, policyIdFor } from "./constants.js";
|
|
42
|
+
import { DuplicatePolicyError } from "./store.js";
|
|
43
|
+
const KIND = ApiResourceKind.iam_policy;
|
|
44
|
+
/**
|
|
45
|
+
* The cloud SQL's scope-tuple exclusions (store.ts): a scope tuple is a
|
|
46
|
+
* row whose principal is a RESOURCE and whose relation is structural. The
|
|
47
|
+
* principal half is derived from the user lane's grantee vocabulary
|
|
48
|
+
* (constants.ts USER_GRANT_PRINCIPAL_KINDS; Q-S9-2) so the writer's "who a
|
|
49
|
+
* person may grant to" and the reader's "what is a person, not a parent"
|
|
50
|
+
* are one definition; `team` stays for the cloud's Java-era rows (not an
|
|
51
|
+
* ApiResourceKind, so no wire spec names it).
|
|
52
|
+
*/
|
|
53
|
+
const NON_STRUCTURAL_PRINCIPAL_KINDS = [
|
|
54
|
+
...USER_GRANT_PRINCIPAL_KINDS.map((kind) => kindEnumName(kind)),
|
|
55
|
+
"team",
|
|
56
|
+
];
|
|
57
|
+
const NON_STRUCTURAL_RELATIONS = ["owner", "creator"];
|
|
58
|
+
export function newResourceIamPolicyStore(store) {
|
|
59
|
+
async function readById(id) {
|
|
60
|
+
try {
|
|
61
|
+
return await store.getResource(KIND, id, IamPolicySchema);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error instanceof ResourceNotFoundError) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Every row of the kind, decoded — the scan behind every non-id read. */
|
|
71
|
+
async function all() {
|
|
72
|
+
const rows = await store.listResources(KIND);
|
|
73
|
+
return rows.map((bytes) => fromBinary(IamPolicySchema, bytes));
|
|
74
|
+
}
|
|
75
|
+
async function where(predicate) {
|
|
76
|
+
return (await all()).filter(predicate);
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
async save(policy) {
|
|
80
|
+
const id = policy.metadata?.id ?? "";
|
|
81
|
+
if (policy.spec === undefined || id !== policyIdFor(policy.spec)) {
|
|
82
|
+
throw new Error("policy id must be derived from its triple");
|
|
83
|
+
}
|
|
84
|
+
if ((await readById(id)) !== undefined) {
|
|
85
|
+
throw new DuplicatePolicyError(`IAM policy '${id}' already exists`);
|
|
86
|
+
}
|
|
87
|
+
await store.saveResource(KIND, id, IamPolicySchema, policy);
|
|
88
|
+
},
|
|
89
|
+
async deleteById(id) {
|
|
90
|
+
await store.deleteResource(KIND, id);
|
|
91
|
+
},
|
|
92
|
+
findById: readById,
|
|
93
|
+
findByPrincipal(principalKind, principalId) {
|
|
94
|
+
return where((policy) => onPrincipal(policy, principalKind, principalId));
|
|
95
|
+
},
|
|
96
|
+
findByResource(resourceKind, resourceId) {
|
|
97
|
+
return where((policy) => onResource(policy, resourceKind, resourceId));
|
|
98
|
+
},
|
|
99
|
+
findByPrincipalAndResource(principalKind, principalId, resourceKind, resourceId) {
|
|
100
|
+
return where((policy) => onPrincipal(policy, principalKind, principalId) &&
|
|
101
|
+
onResource(policy, resourceKind, resourceId));
|
|
102
|
+
},
|
|
103
|
+
findByResourceWithRelations(resourceKind, resourceId, relations) {
|
|
104
|
+
return where((policy) => onResource(policy, resourceKind, resourceId) &&
|
|
105
|
+
relations.includes(relationOf(policy)));
|
|
106
|
+
},
|
|
107
|
+
async countDistinctPrincipalsByResource(resourceKind, resourceId, principalKind, relations) {
|
|
108
|
+
const principals = new Set();
|
|
109
|
+
for (const policy of await all()) {
|
|
110
|
+
if (onResource(policy, resourceKind, resourceId) &&
|
|
111
|
+
relations.includes(relationOf(policy)) &&
|
|
112
|
+
(principalKind === undefined ||
|
|
113
|
+
policy.spec?.principal?.kind === principalKind)) {
|
|
114
|
+
principals.add(`${policy.spec?.principal?.kind ?? ""}:${policy.spec?.principal?.id ?? ""}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return principals.size;
|
|
118
|
+
},
|
|
119
|
+
async findScopeTuple(resourceKind, resourceId) {
|
|
120
|
+
return (await all()).find((policy) => onResource(policy, resourceKind, resourceId) &&
|
|
121
|
+
!NON_STRUCTURAL_PRINCIPAL_KINDS.includes(policy.spec?.principal?.kind ?? "") &&
|
|
122
|
+
!NON_STRUCTURAL_RELATIONS.includes(relationOf(policy)));
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function onPrincipal(policy, kind, id) {
|
|
127
|
+
return (policy.spec?.principal?.kind === kind && policy.spec?.principal?.id === id);
|
|
128
|
+
}
|
|
129
|
+
function onResource(policy, kind, id) {
|
|
130
|
+
return (policy.spec?.resource?.kind === kind && policy.spec?.resource?.id === id);
|
|
131
|
+
}
|
|
132
|
+
function relationOf(policy) {
|
|
133
|
+
return policy.spec?.relation ?? "";
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=resource-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-store.js","sourceRoot":"","sources":["../../../src/domain/iampolicy/resource-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ResourceAuthorizationLifecycle } from "../../extensions/resource-authorization.js";
|
|
2
|
+
import type { AccountsByCaller } from "../identityaccount/resolve.js";
|
|
3
|
+
import type { IamPolicyGrantPath } from "./grant-path.js";
|
|
4
|
+
export interface BuiltInRoleLifecycleDeps {
|
|
5
|
+
readonly grantPath: IamPolicyGrantPath;
|
|
6
|
+
readonly accounts: AccountsByCaller;
|
|
7
|
+
}
|
|
8
|
+
export declare function newBuiltInRoleLifecycle(deps: BuiltInRoleLifecycleDeps): ResourceAuthorizationLifecycle;
|
|
9
|
+
//# sourceMappingURL=role-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/domain/iampolicy/role-lifecycle.ts"],"names":[],"mappings":"AAoEA,OAAO,KAAK,EACV,8BAA8B,EAG/B,MAAM,4CAA4C,CAAC;AAGpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;CACrC;AAQD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,wBAAwB,GAC7B,8BAA8B,CAuChC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The built-in role lifecycle (20260913.01, T01_0_plan.md §3a; T01_1_review.md
|
|
3
|
+
* Q-OR-6a): the ResourceAuthorizationLifecycle open source installs when
|
|
4
|
+
* no unit registers one, under the built-in authorization posture
|
|
5
|
+
* (boot/compose.ts `builtInAuthorization`). It is the ROW writer of that
|
|
6
|
+
* posture at the resource lifecycle points — the one arm that makes an
|
|
7
|
+
* organization's creator its owner without an administrator — and nothing
|
|
8
|
+
* more. The cloud's tuple driver plays the same part for tuples; a
|
|
9
|
+
* composition that registers one never sees this object.
|
|
10
|
+
*
|
|
11
|
+
* It is handed to the ORGANIZATION and IDENTITY-ACCOUNT controllers only
|
|
12
|
+
* (slice 4 ruling Q-S4-8), the two kinds whose events it reads. A
|
|
13
|
+
* lifecycle on a controller turns on the tuple steps' full event
|
|
14
|
+
* resolution for that kind, and resolution fails a request whose
|
|
15
|
+
* configured parent id is missing — Java parity the cloud relies on, and
|
|
16
|
+
* a state open source admits by contract for other kinds (a memory
|
|
17
|
+
* captured with no credential has no subject). Every other controller
|
|
18
|
+
* keeps the composed driver (undefined in open source) and its steps
|
|
19
|
+
* no-op before any resolution, byte-identical to before this entry.
|
|
20
|
+
*
|
|
21
|
+
* What it writes:
|
|
22
|
+
* - `organization` created with DIRECT attribution (the kind's
|
|
23
|
+
* owner_type in kind_meta — the event says so; the driver follows it
|
|
24
|
+
* exactly as the cloud's does) by a `user`-class caller that RESOLVES
|
|
25
|
+
* to an account: one `owner` row for that account. Only `organization`,
|
|
26
|
+
* because that row is what the Members page and entry 3's admin rule
|
|
27
|
+
* read; an owner row on an agent would be the per-resource grant the
|
|
28
|
+
* grant scope keeps Enterprise (Q-OR-3).
|
|
29
|
+
* - `organization` and `identity_account` deleted: every row naming the
|
|
30
|
+
* resource on either side goes, through the grant path's bidirectional
|
|
31
|
+
* cleanup — the delete chains' CleanupIamPolicies step calls this, so
|
|
32
|
+
* the rows die with the resource.
|
|
33
|
+
*
|
|
34
|
+
* Who the row is FOR, and who it says wrote it. The event's caller is the
|
|
35
|
+
* position-1 identity, which is an account id only when a verifier
|
|
36
|
+
* resolved it: under the trusted-local posture it is the operator's
|
|
37
|
+
* EMAIL (or "system"), and a composition verifier may stamp a raw
|
|
38
|
+
* subject. `accountForCaller` (domain/identityaccount/resolve.ts) is the
|
|
39
|
+
* domain's one statement of "the caller's account" — the two reads
|
|
40
|
+
* whoAmI makes — so this object and whoAmI cannot disagree (Q-S4-1). The
|
|
41
|
+
* row is then granted AS the account (`identityId` re-stamped, the
|
|
42
|
+
* `provisionMyAccount` idiom), so every policy row's `created_by.id` is
|
|
43
|
+
* an account id — never an email, never an idp subject. A caller that
|
|
44
|
+
* resolves to no account (an idp-shaped subject before provisioning)
|
|
45
|
+
* writes nothing: the membership rules heal a real person's ownership at
|
|
46
|
+
* first provisioning through the organization's creator stamp
|
|
47
|
+
* (membership.ts, Q-OR-6b), so the guard loses nobody. Non-`user` classes
|
|
48
|
+
* (`internal`, `runner`, a composition's own) write nothing by rule — the
|
|
49
|
+
* roles are people's (Q-OR-6b), and under trusted-local a daemon-origin
|
|
50
|
+
* caller carries the operator's fields and would otherwise resolve.
|
|
51
|
+
*
|
|
52
|
+
* Acyclic by construction: this object sits ON TOP of the grant path and
|
|
53
|
+
* defines neither policy hook. The grant path's own lifecycle is the
|
|
54
|
+
* composed driver (undefined in open source), never this object (S1
|
|
55
|
+
* finding B); the test pins both facts.
|
|
56
|
+
*
|
|
57
|
+
* Faults propagate. The create arm's throw fails the organization create
|
|
58
|
+
* (the step maps it INTERNAL; the row survives, a retry converges through
|
|
59
|
+
* the grant path's duplicate arm); the delete arm's throw is logged and
|
|
60
|
+
* the delete succeeds (the step's best-effort contract).
|
|
61
|
+
*/
|
|
62
|
+
import { create } from "@bufbuild/protobuf";
|
|
63
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
64
|
+
import { OwnerAttributionType } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/authorization_config_pb";
|
|
65
|
+
import { ApiResourceRefSchema } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/spec_pb";
|
|
66
|
+
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
67
|
+
import { kindEnumName } from "../../pipeline/apiresource-meta.js";
|
|
68
|
+
import { accountForCaller } from "../identityaccount/resolve.js";
|
|
69
|
+
import { organizationRole } from "./specs.js";
|
|
70
|
+
/** The kinds whose rows die with the resource — the two sides an organization role names. */
|
|
71
|
+
const CLEANUP_KINDS = new Set([
|
|
72
|
+
ApiResourceKind.organization,
|
|
73
|
+
ApiResourceKind.identity_account,
|
|
74
|
+
]);
|
|
75
|
+
export function newBuiltInRoleLifecycle(deps) {
|
|
76
|
+
const { grantPath, accounts } = deps;
|
|
77
|
+
return {
|
|
78
|
+
async onResourceCreated(event) {
|
|
79
|
+
if (event.kind !== ApiResourceKind.organization ||
|
|
80
|
+
event.ownerAttribution !== OwnerAttributionType.DIRECT ||
|
|
81
|
+
event.caller.callerClass !== "user") {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const account = await accountForCaller(accounts, event.caller);
|
|
85
|
+
const accountId = account?.metadata?.id ?? "";
|
|
86
|
+
if (accountId === "") {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
await grantPath.grant(organizationRole(accountId, IamRole.owner, event.resourceId), { ...event.caller, identityId: accountId });
|
|
90
|
+
},
|
|
91
|
+
async onResourceDeleted(event) {
|
|
92
|
+
if (!CLEANUP_KINDS.has(event.kind)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
await grantPath.cleanupResource(create(ApiResourceRefSchema, {
|
|
96
|
+
kind: kindEnumName(event.kind),
|
|
97
|
+
id: event.resourceId,
|
|
98
|
+
}));
|
|
99
|
+
},
|
|
100
|
+
async onVisibilityChanged() {
|
|
101
|
+
// Visibility is a tuple concern (org-viewer, public-viewer shapes);
|
|
102
|
+
// open source's rows record roles, not visibility.
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=role-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-lifecycle.js","sourceRoot":"","sources":["../../../src/domain/iampolicy/role-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AACtH,OAAO,EAAE,oBAAoB,EAAE,MAAM,wFAAwF,CAAC;AAC9H,OAAO,EAAE,oBAAoB,EAAE,MAAM,qDAAqD,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAC;AAOpE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAO9C,6FAA6F;AAC7F,MAAM,aAAa,GAAiC,IAAI,GAAG,CAAC;IAC1D,eAAe,CAAC,YAAY;IAC5B,eAAe,CAAC,gBAAgB;CACjC,CAAC,CAAC;AAEH,MAAM,UAAU,uBAAuB,CACrC,IAA8B;IAE9B,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACrC,OAAO;QACL,KAAK,CAAC,iBAAiB,CAAC,KAA2B;YACjD,IACE,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,YAAY;gBAC3C,KAAK,CAAC,gBAAgB,KAAK,oBAAoB,CAAC,MAAM;gBACtD,KAAK,CAAC,MAAM,CAAC,WAAW,KAAK,MAAM,EACnC,CAAC;gBACD,OAAO;YACT,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC;YAC9C,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,MAAM,SAAS,CAAC,KAAK,CACnB,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,EAC5D,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,CAC3C,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,iBAAiB,CAAC,KAA2B;YACjD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,OAAO;YACT,CAAC;YACD,MAAM,SAAS,CAAC,eAAe,CAC7B,MAAM,CAAC,oBAAoB,EAAE;gBAC3B,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC9B,EAAE,EAAE,KAAK,CAAC,UAAU;aACrB,CAAC,CACH,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,mBAAmB;YACvB,oEAAoE;YACpE,mDAAmD;QACrD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RoleInfo } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
|
|
2
|
+
/** The allowlist for access-listing queries (Java assignableRelations). */
|
|
3
|
+
export declare function assignableRelations(): ReadonlyArray<string>;
|
|
4
|
+
/** True when the relation names an assignable IAM role, never structural. */
|
|
5
|
+
export declare function isAssignableRole(relation: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Relation string → RoleInfo with display metadata; the default instance
|
|
8
|
+
* for unknown relations (the Java fromRelationString contract).
|
|
9
|
+
*/
|
|
10
|
+
export declare function roleInfoFromRelation(relation: string): RoleInfo;
|
|
11
|
+
//# sourceMappingURL=roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../../src/domain/iampolicy/roles.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mDAAmD,CAAC;AAgDlF,2EAA2E;AAC3E,wBAAgB,mBAAmB,IAAI,aAAa,CAAC,MAAM,CAAC,CAE3D;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAY/D"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IAM role metadata (20260913.01 slice 5): display metadata for the five
|
|
3
|
+
* assignable roles and the assignable-relation allowlist that keeps
|
|
4
|
+
* structural relations (parent links, runtime grants, observability
|
|
5
|
+
* usersets) out of every access listing BY CONSTRUCTION — reads filter to
|
|
6
|
+
* this set rather than maintaining a denylist a new structural relation
|
|
7
|
+
* could slip past. Moved as-is from the cloud's iam/policy/roles.ts, itself
|
|
8
|
+
* the port of Java's apishape/authorization/IamRoleMetadata; the cloud's
|
|
9
|
+
* `grantableRolesFor` did not come along — it lives in
|
|
10
|
+
* pipeline/apiresource-meta.ts as the contract's one read of
|
|
11
|
+
* `kind_meta.grantable_roles`, and the cloud registers its own reading of
|
|
12
|
+
* it as the `policyGrantScope` driver.
|
|
13
|
+
*
|
|
14
|
+
* The four words this table renders for an organization are the four
|
|
15
|
+
* roles every edition grants there (Q-OR-4) and the ladder entry 3's
|
|
16
|
+
* authorizer enforces; the copy is shown verbatim by the console's role
|
|
17
|
+
* badges and selector, so it is contract.
|
|
18
|
+
*/
|
|
19
|
+
import { create } from "@bufbuild/protobuf";
|
|
20
|
+
import { RoleInfoSchema } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
|
|
21
|
+
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
22
|
+
const ROLE_DISPLAY = [
|
|
23
|
+
{
|
|
24
|
+
role: IamRole.owner,
|
|
25
|
+
name: "Owner",
|
|
26
|
+
description: "Full control of the resource including ownership transfer",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
role: IamRole.admin,
|
|
30
|
+
name: "Administrator",
|
|
31
|
+
description: "Administrative access with most permissions except ownership transfer",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
role: IamRole.member,
|
|
35
|
+
name: "Member",
|
|
36
|
+
description: "Read and limited write access to the resource",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
role: IamRole.viewer,
|
|
40
|
+
name: "Viewer",
|
|
41
|
+
description: "Read-only access to the resource",
|
|
42
|
+
},
|
|
43
|
+
// Grantable on agent_channel only (channel-conversations DD-010);
|
|
44
|
+
// omitting it would let the grant succeed while hiding the participant
|
|
45
|
+
// from every access listing (the Java IamRoleMetadataTest lesson).
|
|
46
|
+
{
|
|
47
|
+
role: IamRole.participant,
|
|
48
|
+
name: "Participant",
|
|
49
|
+
description: "Reply to customers and manage conversation takeover on a channel",
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
const RELATION_TO_DISPLAY = new Map(ROLE_DISPLAY.map((entry) => [IamRole[entry.role], entry]));
|
|
53
|
+
/** The allowlist for access-listing queries (Java assignableRelations). */
|
|
54
|
+
export function assignableRelations() {
|
|
55
|
+
return [...RELATION_TO_DISPLAY.keys()];
|
|
56
|
+
}
|
|
57
|
+
/** True when the relation names an assignable IAM role, never structural. */
|
|
58
|
+
export function isAssignableRole(relation) {
|
|
59
|
+
return RELATION_TO_DISPLAY.has(relation);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Relation string → RoleInfo with display metadata; the default instance
|
|
63
|
+
* for unknown relations (the Java fromRelationString contract).
|
|
64
|
+
*/
|
|
65
|
+
export function roleInfoFromRelation(relation) {
|
|
66
|
+
const display = RELATION_TO_DISPLAY.get(relation);
|
|
67
|
+
if (display === undefined) {
|
|
68
|
+
return create(RoleInfoSchema);
|
|
69
|
+
}
|
|
70
|
+
const code = IamRole[display.role];
|
|
71
|
+
return create(RoleInfoSchema, {
|
|
72
|
+
id: code,
|
|
73
|
+
code,
|
|
74
|
+
name: display.name,
|
|
75
|
+
description: display.description,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=roles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../../../src/domain/iampolicy/roles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAC;AASpE,MAAM,YAAY,GAA+B;IAC/C;QACE,IAAI,EAAE,OAAO,CAAC,KAAK;QACnB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,2DAA2D;KACzE;IACD;QACE,IAAI,EAAE,OAAO,CAAC,KAAK;QACnB,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,uEAAuE;KAC1E;IACD;QACE,IAAI,EAAE,OAAO,CAAC,MAAM;QACpB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,+CAA+C;KAC7D;IACD;QACE,IAAI,EAAE,OAAO,CAAC,MAAM;QACpB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,kCAAkC;KAChD;IACD,kEAAkE;IAClE,uEAAuE;IACvE,mEAAmE;IACnE;QACE,IAAI,EAAE,OAAO,CAAC,WAAW;QACzB,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,kEAAkE;KACrE;CACF,CAAC;AAEF,MAAM,mBAAmB,GAAqC,IAAI,GAAG,CACnE,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAC1D,CAAC;AAEF,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,cAAc,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,cAAc,EAAE;QAC5B,EAAE,EAAE,IAAI;QACR,IAAI;QACJ,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IamPolicySpec } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/spec_pb";
|
|
2
|
+
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
3
|
+
/** The relation string a role grants — the enum member's own name. */
|
|
4
|
+
export declare function relationOf(role: IamRole): string;
|
|
5
|
+
/** `identity_account:<accountId>` holds `<role>` on `organization:<organizationId>` — the organization role. */
|
|
6
|
+
export declare function organizationRole(accountId: string, role: IamRole, organizationId: string): IamPolicySpec;
|
|
7
|
+
//# sourceMappingURL=specs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specs.d.ts","sourceRoot":"","sources":["../../../src/domain/iampolicy/specs.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qDAAqD,CAAC;AAEzF,OAAO,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAC;AAIpE,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAKhD;AAED,gHAAgH;AAChH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,EACb,cAAc,EAAE,MAAM,GACrB,aAAa,CAYf"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The IamPolicy specs server code builds ITSELF, spelled once
|
|
3
|
+
* (20260913.01 slice 4). A wire caller hands the domain a spec; the
|
|
4
|
+
* built-in role lifecycle, the membership rules and slice 5's
|
|
5
|
+
* `revokeOrgAccess` and contextual `checkMyPermission` build their own.
|
|
6
|
+
* The derived policy id hashes the spec's exact text (constants.ts
|
|
7
|
+
* `policyIdFor`), so two spellings of one triple would be two rows — this
|
|
8
|
+
* module is where "identity_account:<id> holds <role> on
|
|
9
|
+
* organization:<org>" has one spelling in production code, the way the
|
|
10
|
+
* test support's `orgRole` is that spelling for tests.
|
|
11
|
+
*
|
|
12
|
+
* Kinds are spelled through `kindEnumName` (the ApiResourceRef vocabulary,
|
|
13
|
+
* pipeline/apiresource-meta.ts); relations are the `IamRole` member names,
|
|
14
|
+
* which are the FGA model's relation names and the proto's grantable-role
|
|
15
|
+
* vocabulary. The zero value `iam_role_unspecified` is not a relation and
|
|
16
|
+
* is refused (the `accountIdFor("")` precedent): hashing it would mint a
|
|
17
|
+
* real row for a role nobody holds.
|
|
18
|
+
*/
|
|
19
|
+
import { create } from "@bufbuild/protobuf";
|
|
20
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
21
|
+
import { IamPolicySpecSchema } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/spec_pb";
|
|
22
|
+
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
23
|
+
import { kindEnumName } from "../../pipeline/apiresource-meta.js";
|
|
24
|
+
/** The relation string a role grants — the enum member's own name. */
|
|
25
|
+
export function relationOf(role) {
|
|
26
|
+
if (role === IamRole.iam_role_unspecified) {
|
|
27
|
+
throw new Error("iam_role_unspecified is not a relation");
|
|
28
|
+
}
|
|
29
|
+
return IamRole[role];
|
|
30
|
+
}
|
|
31
|
+
/** `identity_account:<accountId>` holds `<role>` on `organization:<organizationId>` — the organization role. */
|
|
32
|
+
export function organizationRole(accountId, role, organizationId) {
|
|
33
|
+
return create(IamPolicySpecSchema, {
|
|
34
|
+
principal: {
|
|
35
|
+
kind: kindEnumName(ApiResourceKind.identity_account),
|
|
36
|
+
id: accountId,
|
|
37
|
+
},
|
|
38
|
+
relation: relationOf(role),
|
|
39
|
+
resource: {
|
|
40
|
+
kind: kindEnumName(ApiResourceKind.organization),
|
|
41
|
+
id: organizationId,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specs.js","sourceRoot":"","sources":["../../../src/domain/iampolicy/specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AAEtH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAC;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,sEAAsE;AACtE,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,IAAI,IAAI,KAAK,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,IAAa,EACb,cAAsB;IAEtB,OAAO,MAAM,CAAC,mBAAmB,EAAE;QACjC,SAAS,EAAE;YACT,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC,gBAAgB,CAAC;YACpD,EAAE,EAAE,SAAS;SACd;QACD,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC;QAC1B,QAAQ,EAAE;YACR,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC;YAChD,EAAE,EAAE,cAAc;SACnB;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { RevokeOrgAccessInputSchema } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
|
|
2
|
+
import type { ApiResourceRefSchema, IamPolicySpecSchema } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/spec_pb";
|
|
3
|
+
import type { PolicyGrantScope } from "../../extensions/policy-grant-scope.js";
|
|
4
|
+
import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
5
|
+
import type { IamPolicyGrantPath } from "./grant-path.js";
|
|
6
|
+
/** The row a write chain answers — the granted row, or the revoked row (the default instance when there was none). */
|
|
7
|
+
export declare const POLICY_RESULT_KEY = "policyResult";
|
|
8
|
+
/** The `create` chain's role check; see the module header for the four arms. */
|
|
9
|
+
export declare function newValidateGrantableRoleStep(scope: PolicyGrantScope): PipelineStep<typeof IamPolicySpecSchema>;
|
|
10
|
+
/** Grant the spec as the chain's caller; the row (fresh or held) is the result. */
|
|
11
|
+
export declare function newGrantStep(grantPath: IamPolicyGrantPath): PipelineStep<typeof IamPolicySpecSchema>;
|
|
12
|
+
/** Revoke the spec's row; absent, the default instance is the result (Java's idempotent delete). */
|
|
13
|
+
export declare function newRevokeStep(grantPath: IamPolicyGrantPath): PipelineStep<typeof IamPolicySpecSchema>;
|
|
14
|
+
/** Revoke every relation the account holds directly on the organization. */
|
|
15
|
+
export declare function newRevokeOrgAccessStep(grantPath: IamPolicyGrantPath): PipelineStep<typeof RevokeOrgAccessInputSchema>;
|
|
16
|
+
/** Revoke every row naming the ref as resource or principal — the deleted resource's cleanup. */
|
|
17
|
+
export declare function newCleanupResourceStep(grantPath: IamPolicyGrantPath): PipelineStep<typeof ApiResourceRefSchema>;
|
|
18
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../../src/domain/iampolicy/steps.ts"],"names":[],"mappings":"AA4CA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mDAAmD,CAAC;AACpG,OAAO,KAAK,EAEV,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,qDAAqD,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAE/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAS/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAM1D,sHAAsH;AACtH,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,gFAAgF;AAChF,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,gBAAgB,GACtB,YAAY,CAAC,OAAO,mBAAmB,CAAC,CA0C1C;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAC1B,SAAS,EAAE,kBAAkB,GAC5B,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAU1C;AAED,oGAAoG;AACpG,wBAAgB,aAAa,CAC3B,SAAS,EAAE,kBAAkB,GAC5B,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAU1C;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,kBAAkB,GAC5B,YAAY,CAAC,OAAO,0BAA0B,CAAC,CAYjD;AAED,iGAAiG;AACjG,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,kBAAkB,GAC5B,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAQ3C"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IamPolicy pipeline steps (20260913.01 slice 5; Q-S5-1): the domain-local
|
|
3
|
+
* steps the six command chains splice after the shared `Authorize` and
|
|
4
|
+
* `ValidateProto`. The write itself is never here — every step that writes
|
|
5
|
+
* calls the ONE grant and revoke path (grant-path.ts, which owns the
|
|
6
|
+
* cloud#425 orderings, the by-triple read and the wire refusals) and leaves
|
|
7
|
+
* its answer under POLICY_RESULT_KEY for the handler. The chains are
|
|
8
|
+
* deliberately short: `Authorize → ValidateProto → <one of these>`, so the
|
|
9
|
+
* pipeline executor's fault mapping (a step's ConnectError keeps its code;
|
|
10
|
+
* a raw store fault becomes the sanitized INTERNAL) covers the path's two
|
|
11
|
+
* error shapes with no second idiom in the handlers.
|
|
12
|
+
*
|
|
13
|
+
* ValidateGrantableRole (the `create` chain only; `bootstrapPolicy` is the
|
|
14
|
+
* structural lane and skips it) is the one step with branching logic. It
|
|
15
|
+
* runs BEFORE Grant — the cloud's validate-before-write order, so a held
|
|
16
|
+
* legacy row under a role the kind does not grant is refused rather than
|
|
17
|
+
* answered as a duplicate — and reads, in this order (Q-OR-3 as refined;
|
|
18
|
+
* Q-S3-3):
|
|
19
|
+
* 1. the wire refusals: an unknown resource kind is `Unknown resource
|
|
20
|
+
* kind`, never a role sentence — the second line behind the
|
|
21
|
+
* controller's pre-position-1 refusal (Q-S6-1), kept so the step's
|
|
22
|
+
* own contract holds for whoever splices it;
|
|
23
|
+
* 2. the PROTO (`grantableRolesFor`): a kind that lists no role is
|
|
24
|
+
* system-managed in every edition — the cloud's byte-pinned copy,
|
|
25
|
+
* whatever the composed scope claims;
|
|
26
|
+
* 3. the composed SCOPE: a kind it lists nothing for is a per-resource
|
|
27
|
+
* grant this edition does not serve — UNIMPLEMENTED naming the
|
|
28
|
+
* editions that do;
|
|
29
|
+
* 4. proto ∩ scope, in proto order: the role must be in the
|
|
30
|
+
* intersection — the cloud's second copy listing it. Intersecting is
|
|
31
|
+
* what keeps a scope from WIDENING the contract by accident;
|
|
32
|
+
* 5. the PRINCIPAL (Q-S9-2, 2026-09-14; constants.ts
|
|
33
|
+
* USER_GRANT_PRINCIPAL_KINDS): a person grants roles to people — the
|
|
34
|
+
* identity account — and to nothing else. A row whose principal is a
|
|
35
|
+
* resource is a structural link (the hierarchy walk's parent edge),
|
|
36
|
+
* which is `bootstrapPolicy`'s to write; through this lane it would
|
|
37
|
+
* let a right on one organization read another's members. Last, so
|
|
38
|
+
* every answer the cloud's create gives today is unchanged and only
|
|
39
|
+
* the row it should never have written is refused.
|
|
40
|
+
*/
|
|
41
|
+
import { create } from "@bufbuild/protobuf";
|
|
42
|
+
import { Code, ConnectError } from "@connectrpc/connect";
|
|
43
|
+
import { IamPolicySchema } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/api_pb";
|
|
44
|
+
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
45
|
+
import { grantableRolesFor } from "../../pipeline/apiresource-meta.js";
|
|
46
|
+
import { PER_RESOURCE_GRANTS_UNIMPLEMENTED_MESSAGE, USER_GRANT_PRINCIPAL_KINDS, noGrantableRolesMessage, principalNotGrantableMessage, roleNotGrantableMessage, } from "./constants.js";
|
|
47
|
+
import { requireKnownPrincipalKind, requireKnownResourceKind, } from "./wire-refusals.js";
|
|
48
|
+
/** The row a write chain answers — the granted row, or the revoked row (the default instance when there was none). */
|
|
49
|
+
export const POLICY_RESULT_KEY = "policyResult";
|
|
50
|
+
/** The `create` chain's role check; see the module header for the four arms. */
|
|
51
|
+
export function newValidateGrantableRoleStep(scope) {
|
|
52
|
+
return {
|
|
53
|
+
name: "ValidateGrantableRole",
|
|
54
|
+
execute(ctx) {
|
|
55
|
+
const spec = ctx.input;
|
|
56
|
+
const kindName = spec.resource?.kind ?? "";
|
|
57
|
+
const kind = requireKnownResourceKind(kindName);
|
|
58
|
+
const contract = grantableRolesFor(kind);
|
|
59
|
+
if (contract.length === 0) {
|
|
60
|
+
throw new ConnectError(noGrantableRolesMessage(kindName), Code.InvalidArgument);
|
|
61
|
+
}
|
|
62
|
+
const scoped = new Set(scope.grantableRoles(kind));
|
|
63
|
+
if (scoped.size === 0) {
|
|
64
|
+
throw new ConnectError(PER_RESOURCE_GRANTS_UNIMPLEMENTED_MESSAGE, Code.Unimplemented);
|
|
65
|
+
}
|
|
66
|
+
const grantable = contract.filter((role) => scoped.has(role));
|
|
67
|
+
if (!grantable.some((role) => IamRole[role] === spec.relation)) {
|
|
68
|
+
throw new ConnectError(roleNotGrantableMessage(spec.relation, kindName, grantable.map((role) => IamRole[role])), Code.InvalidArgument);
|
|
69
|
+
}
|
|
70
|
+
const principalKindName = spec.principal?.kind ?? "";
|
|
71
|
+
const principalKind = requireKnownPrincipalKind(principalKindName);
|
|
72
|
+
if (!USER_GRANT_PRINCIPAL_KINDS.includes(principalKind)) {
|
|
73
|
+
throw new ConnectError(principalNotGrantableMessage(principalKindName), Code.InvalidArgument);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** Grant the spec as the chain's caller; the row (fresh or held) is the result. */
|
|
79
|
+
export function newGrantStep(grantPath) {
|
|
80
|
+
return {
|
|
81
|
+
name: "Grant",
|
|
82
|
+
async execute(ctx) {
|
|
83
|
+
const { policy } = await grantPath.grant(ctx.input, ctx.callerIdentity);
|
|
84
|
+
ctx.set(POLICY_RESULT_KEY, policy);
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Revoke the spec's row; absent, the default instance is the result (Java's idempotent delete). */
|
|
89
|
+
export function newRevokeStep(grantPath) {
|
|
90
|
+
return {
|
|
91
|
+
name: "Revoke",
|
|
92
|
+
async execute(ctx) {
|
|
93
|
+
const revoked = await grantPath.revokeBySpec(ctx.input);
|
|
94
|
+
ctx.set(POLICY_RESULT_KEY, revoked ?? create(IamPolicySchema));
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** Revoke every relation the account holds directly on the organization. */
|
|
99
|
+
export function newRevokeOrgAccessStep(grantPath) {
|
|
100
|
+
return {
|
|
101
|
+
name: "RevokeOrgAccess",
|
|
102
|
+
execute(ctx) {
|
|
103
|
+
return grantPath.revokeOrgAccess(ctx.input.identityAccountId, ctx.input.organizationId);
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Revoke every row naming the ref as resource or principal — the deleted resource's cleanup. */
|
|
108
|
+
export function newCleanupResourceStep(grantPath) {
|
|
109
|
+
return {
|
|
110
|
+
name: "CleanupResource",
|
|
111
|
+
execute(ctx) {
|
|
112
|
+
const ref = ctx.input;
|
|
113
|
+
return grantPath.cleanupResource(ref);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.js","sourceRoot":"","sources":["../../../src/domain/iampolicy/steps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PortContractCase, PortContractFixture } from "../../store/port-contract.js";
|
|
2
|
+
import type { IamPolicyStore } from "./store.js";
|
|
3
|
+
/** The runner's fixture over this port — the name a driver's test and the barrel know it by. */
|
|
4
|
+
export type IamPolicyStoreContractFixture = PortContractFixture<IamPolicyStore>;
|
|
5
|
+
export type IamPolicyStoreContractCase = PortContractCase;
|
|
6
|
+
/** The port's cases over `makeFixture`, one fresh fixture per case. */
|
|
7
|
+
export declare function iamPolicyStoreContract(makeFixture: () => Promise<IamPolicyStoreContractFixture>): ReadonlyArray<IamPolicyStoreContractCase>;
|
|
8
|
+
//# sourceMappingURL=store-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-contract.d.ts","sourceRoot":"","sources":["../../../src/domain/iampolicy/store-contract.ts"],"names":[],"mappings":"AAgDA,OAAO,KAAK,EACV,gBAAgB,EAEhB,mBAAmB,EACpB,MAAM,8BAA8B,CAAC;AAOtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,gGAAgG;AAChG,MAAM,MAAM,6BAA6B,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;AAEhF,MAAM,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AA4X1D,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,OAAO,CAAC,6BAA6B,CAAC,GACxD,aAAa,CAAC,0BAA0B,CAAC,CAE3C"}
|