@kindgi/authz 0.1.8 → 0.1.9-rc.1

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 CHANGED
@@ -8,7 +8,7 @@ Give every enforcement site one vocabulary — which object types exist, which a
8
8
 
9
9
  ## Exports
10
10
 
11
- - **Vocabulary** — `OBJECT_TYPES` / `ObjectType`, `ACTIONS` / `Action`, `ACTION_TO_RELATION` (e.g. `read` → `can_read`), `OBJECT_ACTIONS` (the actions meaningful per object type, so a PEP can reject `rotate` on an agent before calling FGA), `ResourceRef`, `resourceKey(ref)`, `ref(type, id)`.
11
+ - **Vocabulary** — `OBJECT_TYPES` / `ObjectType`, `ACTIONS` / `Action`, `ACTION_TO_RELATION` (e.g. `read` → `can_read`), `OBJECT_ACTIONS` (the actions meaningful per object type, so a PEP can reject `rotate` on an agent before calling FGA), `CHECK_ONLY_ACTIONS` (actions a check may ask that `OBJECT_ACTIONS` doesn't list, so no permissions report names them: a project's `call` and `execute`), `ResourceRef`, `resourceKey(ref)`, `ref(type, id)`.
12
12
  - **Principals** — `Principal` (`actor`, optional `onBehalfOf`, optional `scope`), `PrincipalRef`, `PrincipalKind` (`user`, `agent`, `service_account`, `system`), `DownscopedPermissions` (`allowedActions` / `deniedActions`).
13
13
  - `userPrincipal`, `systemPrincipal`, `serviceAccountPrincipal`, `delegate(actor, onBehalfOf, scope?)` (throws on cross-tenant delegation), `downscope(principal, scope)`.
14
14
  - `fgaSubject(ref)` — the FGA subject string for a principal; `system` maps to `user:system`.
package/dist/types.d.ts CHANGED
@@ -1,9 +1,26 @@
1
- export declare const OBJECT_TYPES: readonly ["tenant", "org", "team", "project", "user", "agent", "flow", "tool", "guardrail", "eval_suite", "trigger", "conversation", "secret", "env", "mcp_endpoint", "run"];
1
+ export declare const OBJECT_TYPES: readonly ["tenant", "org", "team", "project", "user", "service_account", "agent", "flow", "tool", "guardrail", "eval_suite", "trigger", "conversation", "secret", "env", "mcp_endpoint", "run"];
2
2
  export type ObjectType = (typeof OBJECT_TYPES)[number];
3
- export declare const ACTIONS: readonly ["read", "write", "delete", "admin", "execute", "invoke", "publish", "rotate", "fire", "cancel", "promote"];
3
+ export declare const ACTIONS: readonly ["read", "write", "delete", "admin", "execute", "invoke", "publish", "rotate", "fire", "cancel", "promote", "act_as", "call"];
4
4
  export type Action = (typeof ACTIONS)[number];
5
5
  export declare const ACTION_TO_RELATION: Record<Action, string>;
6
6
  export declare const OBJECT_ACTIONS: Record<ObjectType, readonly Action[]>;
7
+ /**
8
+ * Actions a check may ask of a type that `OBJECT_ACTIONS` doesn't list.
9
+ * The model defines them, but nothing reports them: `OBJECT_ACTIONS` is
10
+ * also the list a caller's permissions report and the role capabilities
11
+ * name per type (`RoleActions`), and clients validate that list, so an
12
+ * action added there is a change on the wire.
13
+ *
14
+ * A project's `call` and `execute` are what running an agent, a flow or
15
+ * an eval suite asks of the project the run is in, when the item is
16
+ * served by more than one project: `call` (an editor or a caller of the
17
+ * project) for an agent, `execute` (an editor or an executor) for a flow
18
+ * or a suite. They're the rights an item inherits from its project as
19
+ * `execute`, asked of the project itself.
20
+ */
21
+ export declare const CHECK_ONLY_ACTIONS: Partial<Record<ObjectType, readonly Action[]>>;
22
+ export declare const TENANT_GLOBAL_TYPES: readonly ["tenant", "org", "team", "user", "service_account"];
23
+ export declare const PROJECT_SCOPED_TYPES: readonly ObjectType[];
7
24
  export interface ResourceRef {
8
25
  readonly type: ObjectType;
9
26
  readonly id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,YAAY,8KAqBf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,OAAO,sHAYV,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9C,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAYrD,CAAC;AAIF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAoBhE,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,YAAY,iMA0Bf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,OAAO,wIAiBV,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9C,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAcrD,CAAC;AAIF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAwBhE,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC,CAE7E,CAAC;AAKF,eAAO,MAAM,mBAAmB,+DAAgE,CAAC;AAUjG,eAAO,MAAM,oBAAoB,EAAE,SAAS,UAAU,EAErD,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAEpD"}
package/dist/types.js CHANGED
@@ -8,6 +8,8 @@
8
8
  // - Action verb enum (application-facing vocabulary for PEP callers)
9
9
  // - Action → computed-relation mapping (PEP → FGA check translation)
10
10
  // - Object → allowed-actions catalog (guards against category errors)
11
+ // - Project-scoped type list (`PROJECT_SCOPED_TYPES`): the single source
12
+ // of truth for which types role capabilities and `my-access` report
11
13
  //
12
14
  // Consumers:
13
15
  // - Principal construction (`principal.ts`) builds {actor, onBehalfOf?}
@@ -21,6 +23,11 @@ export const OBJECT_TYPES = [
21
23
  'team',
22
24
  'project',
23
25
  'user',
26
+ // A service account is a tenant-global, non-human identity, like `user`
27
+ // not granted through project roles. `act_as` on it is a tenant-admin
28
+ // delegation (naming it as a trigger's owner), never a project grant, so
29
+ // it is kept out of `PROJECT_SCOPED_TYPES` below.
30
+ 'service_account',
24
31
  // Content (project-scoped, user-authored)
25
32
  'agent',
26
33
  'flow',
@@ -48,6 +55,11 @@ export const ACTIONS = [
48
55
  'fire',
49
56
  'cancel',
50
57
  'promote',
58
+ // Delegation: naming a principal as the one a trigger's runs act as.
59
+ 'act_as',
60
+ // Running an agent in a project: asked of the project only
61
+ // (`CHECK_ONLY_ACTIONS`).
62
+ 'call',
51
63
  ];
52
64
  export const ACTION_TO_RELATION = {
53
65
  read: 'can_read',
@@ -61,6 +73,8 @@ export const ACTION_TO_RELATION = {
61
73
  fire: 'can_fire',
62
74
  cancel: 'can_cancel',
63
75
  promote: 'can_promote',
76
+ act_as: 'can_act_as',
77
+ call: 'can_call',
64
78
  };
65
79
  // Which verbs are meaningful for which object types. A PEP uses this to
66
80
  // reject e.g. `rotate` on `agent:X` before calling FGA.
@@ -70,6 +84,10 @@ export const OBJECT_ACTIONS = {
70
84
  team: ['read', 'admin'],
71
85
  project: ['read', 'write', 'admin', 'delete'],
72
86
  user: [],
87
+ // Only `act_as`: a tenant admin may name this service account as a
88
+ // trigger's owner (so the trigger's runs act as it). No read/write/etc.
89
+ // here — the account's lifecycle is its binding's, not an authz object's.
90
+ service_account: ['act_as'],
73
91
  agent: ['read', 'write', 'delete', 'admin', 'execute', 'publish', 'promote'],
74
92
  flow: ['read', 'write', 'delete', 'admin', 'execute', 'publish'],
75
93
  tool: ['read', 'write', 'delete', 'admin', 'invoke'],
@@ -82,6 +100,36 @@ export const OBJECT_ACTIONS = {
82
100
  mcp_endpoint: ['read', 'write', 'delete', 'admin'],
83
101
  run: ['read', 'cancel', 'delete'],
84
102
  };
103
+ /**
104
+ * Actions a check may ask of a type that `OBJECT_ACTIONS` doesn't list.
105
+ * The model defines them, but nothing reports them: `OBJECT_ACTIONS` is
106
+ * also the list a caller's permissions report and the role capabilities
107
+ * name per type (`RoleActions`), and clients validate that list, so an
108
+ * action added there is a change on the wire.
109
+ *
110
+ * A project's `call` and `execute` are what running an agent, a flow or
111
+ * an eval suite asks of the project the run is in, when the item is
112
+ * served by more than one project: `call` (an editor or a caller of the
113
+ * project) for an agent, `execute` (an editor or an executor) for a flow
114
+ * or a suite. They're the rights an item inherits from its project as
115
+ * `execute`, asked of the project itself.
116
+ */
117
+ export const CHECK_ONLY_ACTIONS = {
118
+ project: ['call', 'execute'],
119
+ };
120
+ // Tenant-global identities and structural boundaries: object types that are
121
+ // NOT granted through project roles. A service account is one of these — its
122
+ // `act_as` is a tenant-admin delegation, not a project capability.
123
+ export const TENANT_GLOBAL_TYPES = ['tenant', 'org', 'team', 'user', 'service_account'];
124
+ // The object types reported per-type in role capabilities (the API's
125
+ // `RoleActionsSchema` / `normalizeCapabilities`). ONE source of truth within
126
+ // this SDK: every consumer here imports this list, so the capabilities wire
127
+ // shape stays consistent. The runtime's `my-access` projection keeps its own
128
+ // positively-written list for now and so CAN differ; the runtime change that
129
+ // adds `service_account` switches that projection to import this list, after
130
+ // which the two can't drift. Tenant-global types (`TENANT_GLOBAL_TYPES`) are
131
+ // left out; new project-scoped content types are included automatically.
132
+ export const PROJECT_SCOPED_TYPES = OBJECT_TYPES.filter((t) => !TENANT_GLOBAL_TYPES.includes(t));
85
133
  export function resourceKey(ref) {
86
134
  return `${ref.type}:${ref.id}`;
87
135
  }
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/authz",
3
- "version": "0.1.8",
3
+ "version": "0.1.9-rc.1",
4
4
  "description": "Kindgi™ authorization shape. The public vocabulary and interfaces of Kindgi's authorization stack: Action verbs (read/write/execute/…), ObjectType enum (agent/flow/tool/…), ResourceRef, Principal (who is calling, with delegation and downscoping), the AuthzCheckBinding decision-point interface and its Decision (allow/deny + reason), FGA tuple builders and the TupleEnqueueHook outbox contract, the 403 DenyPayload shape, and reviewer roles. Types and pure functions — no runtime state. The FGA store, the check implementation and the tuple worker are supplied by the deployment.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -28,7 +28,7 @@
28
28
  "README.md"
29
29
  ],
30
30
  "dependencies": {
31
- "@kindgi/types": "0.1.8"
31
+ "@kindgi/types": "0.1.9-rc.1"
32
32
  },
33
33
  "engines": {
34
34
  "node": ">=22.12.0"
package/src/types.ts CHANGED
@@ -9,6 +9,8 @@
9
9
  // - Action verb enum (application-facing vocabulary for PEP callers)
10
10
  // - Action → computed-relation mapping (PEP → FGA check translation)
11
11
  // - Object → allowed-actions catalog (guards against category errors)
12
+ // - Project-scoped type list (`PROJECT_SCOPED_TYPES`): the single source
13
+ // of truth for which types role capabilities and `my-access` report
12
14
  //
13
15
  // Consumers:
14
16
  // - Principal construction (`principal.ts`) builds {actor, onBehalfOf?}
@@ -23,6 +25,11 @@ export const OBJECT_TYPES = [
23
25
  'team',
24
26
  'project',
25
27
  'user',
28
+ // A service account is a tenant-global, non-human identity, like `user`
29
+ // not granted through project roles. `act_as` on it is a tenant-admin
30
+ // delegation (naming it as a trigger's owner), never a project grant, so
31
+ // it is kept out of `PROJECT_SCOPED_TYPES` below.
32
+ 'service_account',
26
33
  // Content (project-scoped, user-authored)
27
34
  'agent',
28
35
  'flow',
@@ -53,6 +60,11 @@ export const ACTIONS = [
53
60
  'fire',
54
61
  'cancel',
55
62
  'promote',
63
+ // Delegation: naming a principal as the one a trigger's runs act as.
64
+ 'act_as',
65
+ // Running an agent in a project: asked of the project only
66
+ // (`CHECK_ONLY_ACTIONS`).
67
+ 'call',
56
68
  ] as const;
57
69
 
58
70
  export type Action = (typeof ACTIONS)[number];
@@ -69,6 +81,8 @@ export const ACTION_TO_RELATION: Record<Action, string> = {
69
81
  fire: 'can_fire',
70
82
  cancel: 'can_cancel',
71
83
  promote: 'can_promote',
84
+ act_as: 'can_act_as',
85
+ call: 'can_call',
72
86
  };
73
87
 
74
88
  // Which verbs are meaningful for which object types. A PEP uses this to
@@ -79,6 +93,10 @@ export const OBJECT_ACTIONS: Record<ObjectType, readonly Action[]> = {
79
93
  team: ['read', 'admin'],
80
94
  project: ['read', 'write', 'admin', 'delete'],
81
95
  user: [],
96
+ // Only `act_as`: a tenant admin may name this service account as a
97
+ // trigger's owner (so the trigger's runs act as it). No read/write/etc.
98
+ // here — the account's lifecycle is its binding's, not an authz object's.
99
+ service_account: ['act_as'],
82
100
 
83
101
  agent: ['read', 'write', 'delete', 'admin', 'execute', 'publish', 'promote'],
84
102
  flow: ['read', 'write', 'delete', 'admin', 'execute', 'publish'],
@@ -95,6 +113,41 @@ export const OBJECT_ACTIONS: Record<ObjectType, readonly Action[]> = {
95
113
  run: ['read', 'cancel', 'delete'],
96
114
  };
97
115
 
116
+ /**
117
+ * Actions a check may ask of a type that `OBJECT_ACTIONS` doesn't list.
118
+ * The model defines them, but nothing reports them: `OBJECT_ACTIONS` is
119
+ * also the list a caller's permissions report and the role capabilities
120
+ * name per type (`RoleActions`), and clients validate that list, so an
121
+ * action added there is a change on the wire.
122
+ *
123
+ * A project's `call` and `execute` are what running an agent, a flow or
124
+ * an eval suite asks of the project the run is in, when the item is
125
+ * served by more than one project: `call` (an editor or a caller of the
126
+ * project) for an agent, `execute` (an editor or an executor) for a flow
127
+ * or a suite. They're the rights an item inherits from its project as
128
+ * `execute`, asked of the project itself.
129
+ */
130
+ export const CHECK_ONLY_ACTIONS: Partial<Record<ObjectType, readonly Action[]>> = {
131
+ project: ['call', 'execute'],
132
+ };
133
+
134
+ // Tenant-global identities and structural boundaries: object types that are
135
+ // NOT granted through project roles. A service account is one of these — its
136
+ // `act_as` is a tenant-admin delegation, not a project capability.
137
+ export const TENANT_GLOBAL_TYPES = ['tenant', 'org', 'team', 'user', 'service_account'] as const;
138
+
139
+ // The object types reported per-type in role capabilities (the API's
140
+ // `RoleActionsSchema` / `normalizeCapabilities`). ONE source of truth within
141
+ // this SDK: every consumer here imports this list, so the capabilities wire
142
+ // shape stays consistent. The runtime's `my-access` projection keeps its own
143
+ // positively-written list for now and so CAN differ; the runtime change that
144
+ // adds `service_account` switches that projection to import this list, after
145
+ // which the two can't drift. Tenant-global types (`TENANT_GLOBAL_TYPES`) are
146
+ // left out; new project-scoped content types are included automatically.
147
+ export const PROJECT_SCOPED_TYPES: readonly ObjectType[] = OBJECT_TYPES.filter(
148
+ (t) => !(TENANT_GLOBAL_TYPES as readonly string[]).includes(t),
149
+ );
150
+
98
151
  export interface ResourceRef {
99
152
  readonly type: ObjectType;
100
153
  readonly id: string;