@tinycloud/operations 0.4.0 → 0.5.0-beta.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.
@@ -1,6 +1,7 @@
1
- import { ValidatedRuntimeDelegation, RuntimeDelegationActivator, PortableDelegation, PermissionEntry } from '@tinycloud/node-sdk';
1
+ import { PermissionEntry, ValidatedRuntimeDelegation, RuntimeDelegationActivator, PortableDelegation } from '@tinycloud/node-sdk';
2
2
  import { O as OperationSpaceResolver } from './authority-ofwbEqmj.cjs';
3
- import { S as StoredGrantSkipReason } from './contract-BRwWJpPs.cjs';
3
+ import { S as StoredGrantSkipReason, b as OperationWarning } from './contract-DfyrluLB.cjs';
4
+ export { c as STORED_GRANT_SKIP_REASONS } from './contract-DfyrluLB.cjs';
4
5
  import '@tinycloud/sdk-core';
5
6
 
6
7
  /** Creates the one owner-aware resolver shared by operation matching paths. */
@@ -25,8 +26,8 @@ declare function operationSpaceResolver(node: unknown, ownerSpace?: string): (sp
25
26
  * signed capabilities (`cli-grant:<cid>`). Their signed-login records carry
26
27
  * the `siweProof` replay verifies them from.
27
28
  *
28
- * Signed-login records the CLI stored before it kept a `siweProof` cannot be
29
- * verified here and keep their legacy CLI replay.
29
+ * Signed-login records the CLI stored without a `siweProof` cannot be
30
+ * verified from signed bytes and are not installed by either runtime.
30
31
  *
31
32
  * The binding is local profile data. It stops records written by any other
32
33
  * path from granting authority. It does not stop someone who can write the
@@ -38,34 +39,21 @@ declare const BINDING_NOTES: Record<BindingSource, string>;
38
39
  /** The per-profile marker: present once that profile's unbound records were migrated. */
39
40
  declare function bindingMigrationPath(profile: string): string;
40
41
  /**
41
- * How replay treats a stored record:
42
+ * Compact and signed-login records require a valid request binding and signed
43
+ * proof. A legacy record with no proof is classified `other` only so replay
44
+ * can report `proof_missing`; it never installs. Malformed headers are refused.
42
45
  *
43
- * - `compact` and `signed-login` records go through validated activation and
44
- * the binding rule.
45
- * - `other` records keep the CLI's legacy replay: an unbound record whose
46
- * bytes are not compact and that has no `siweProof`, which is how earlier
47
- * CLI releases stored their own signed-login grants. The operations runtime
48
- * never installs them.
49
- * - `refused` records install nothing anywhere.
50
- *
51
- * A record is `refused` unless its `delegationHeader` has exactly one own
52
- * key, `Authorization`, with a string value: header names are matched
53
- * case-insensitively on the wire, and other value types are stringified, so
54
- * any other shape could reach the node as authorization bytes this rule never
55
- * read. Bytes containing a `.` are never `other`: a CACAO has none, and
56
- * validated activation refuses anything compact-shaped that it cannot parse.
57
- * A record with an `authorityRequest` (valid or not) is never `other`: the
58
- * legacy path cannot hold it to a binding, so dropping a `siweProof` cannot
59
- * route a bound signed-login delegation around its binding.
46
+ * A header must contain exactly one `Authorization` string key: other shapes
47
+ * might reach the node as authorization bytes this rule never examined.
60
48
  */
61
49
  declare function storedDelegationKind(entry: unknown): "compact" | "signed-login" | "other" | "refused";
62
- /**
63
- * What replay holds a stored record to: its binding's `requested`, `"signed"`
64
- * for an unbound compact record before the profile has migrated (it installs
65
- * with its own signed authority, as before bindings existed), or `undefined`
66
- * when the record installs nothing.
67
- */
68
- declare function replayLimit(entry: unknown, migrated: boolean): readonly PermissionEntry[] | "signed" | undefined;
50
+ /** A record replays only within a valid stored request binding. */
51
+ declare function replayLimit(entry: unknown): readonly PermissionEntry[] | undefined;
52
+ /** Match node-sdk's normalization before validating a compact signature. */
53
+ declare function withoutBearer(authorization: string): string;
54
+ type StoredDelegationSource = "cli-grant" | "unbound-import" | "migration" | "request" | "legacy" | "unknown";
55
+ /** Constrained labels only; never publish untrusted request IDs or audit notes. */
56
+ declare function storedDelegationSource(entry: unknown): StoredDelegationSource;
69
57
  /**
70
58
  * Binds the record of one of the CLI's own grants, already checked against
71
59
  * the request it answers, to exactly the capabilities its signed bytes grant.
@@ -77,12 +65,10 @@ declare function bindCliGrant<T extends {
77
65
  readonly delegation: PortableDelegation;
78
66
  }>(node: RuntimeDelegationActivator, record: T, host: string): Promise<T & Record<"authorityRequest" | "authorityRequestAudit", unknown>>;
79
67
  /**
80
- * Validates and activates a compact delegation that `tc auth import` received
81
- * without a stored request, through the same validated activation replay uses,
82
- * and returns its record bound to exactly the capabilities its signed bytes
83
- * grant. Throws when validation or activation fails.
68
+ * Validates and activates an imported compact or signed-login delegation,
69
+ * binding its record to exactly its verified signed capabilities.
84
70
  */
85
- declare function activateUnboundCompactImport(node: RuntimeDelegationActivator, delegation: PortableDelegation, host: string): Promise<{
71
+ declare function activateUnboundImport(node: RuntimeDelegationActivator, delegation: PortableDelegation, host: string): Promise<{
86
72
  delegation: PortableDelegation;
87
73
  permissions: PermissionEntry[];
88
74
  } & Record<string, unknown>>;
@@ -100,26 +86,18 @@ declare function mergeDelegationsWithoutRequest(stored: readonly unknown[], inco
100
86
  };
101
87
  } & Record<string, unknown>)[]): unknown[];
102
88
  /**
103
- * Runs before replay reads the profile's records, so those records and the
104
- * migration marker agree. Returns whether the profile has migrated.
89
+ * Runs migration before replay reads the profile's records. Returns whether
90
+ * the marker exists; replay refuses unbound records either way.
105
91
  *
106
- * Migration runs under the profile lock, and only while the profile's
107
- * persisted session is still the one `node` restored: a session rotated since
108
- * the restore leaves migration to a runtime of the new session. Each compact
109
- * record with no `authorityRequest` is handled on its own: if validated
110
- * activation can read its signed capabilities (CID, expiry, audience and
111
- * declared resources checked, nothing activated) and they form a valid
112
- * binding, the record is bound to exactly those capabilities; otherwise it
113
- * stays unbound, is listed in the marker's `unbound`, and installs nothing
114
- * after migration. A compact record whose capabilities cannot be read could
115
- * not activate for this session either. `migrate` must be false unless `node`
92
+ * Migration runs under the profile lock, and only while the persisted session
93
+ * is still the one `node` restored. Each unbound compact record is checked
94
+ * without activation and bound to exactly its signed capabilities, or left
95
+ * unbound when validation fails. `migrate` must be false unless the node
116
96
  * holds the profile's own restored session.
117
97
  *
118
- * Migration is best-effort and restartable. The bound records are written
119
- * first and the marker last; a busy lock or any failure before the marker
120
- * leaves the profile unmigrated, so this runtime replays under the
121
- * pre-migration rule and the next one migrates again. Records already bound
122
- * by an interrupted run keep their bindings.
98
+ * Migration is best-effort and restartable. Bound records are written before
99
+ * the marker; a busy lock or failure leaves migration for a later runtime.
100
+ * Records already bound by an interrupted run keep their bindings.
123
101
  */
124
102
  declare function prepareStoredDelegationReplay(profile: string, node: RuntimeDelegationActivator, options: {
125
103
  readonly host: string;
@@ -140,21 +118,57 @@ type StoredDelegationReplay = {
140
118
  readonly status: "not-replayed";
141
119
  };
142
120
  /**
143
- * Replays one stored record under the binding rule. A record with a valid
144
- * binding installs only if its signed capabilities fit inside it. Before the
145
- * profile has migrated, an unbound compact record installs with its signed
146
- * authority as it always did; after, it installs nothing. A signed-login
147
- * record installs only with a binding. A record with neither compact bytes
148
- * nor a `siweProof` cannot be verified here and installs nothing. Never
149
- * throws, and never reports exception text: stored data is untrusted
150
- * transport material, and messages can quote it or a node's response.
121
+ * The single stored-grant replay path for CLI and canonical runtimes.
122
+ * Migration runs before the store read; CID deduplication affects authority
123
+ * only, not the per-record fixed-code skip diagnostics.
124
+ */
125
+ declare function replayProfileDelegations(profile: string, node: RuntimeDelegationActivator, options: {
126
+ readonly host: string;
127
+ readonly migrate: boolean;
128
+ readonly resolveSpace: OperationSpaceResolver;
129
+ }): Promise<{
130
+ installed: ValidatedRuntimeDelegation[];
131
+ warnings: OperationWarning[];
132
+ }>;
133
+ /** Return an audience only after the exact compact bytes, CID and signature verify. */
134
+ declare function verifiedCompactAudience(node: RuntimeDelegationActivator, delegation: PortableDelegation): string | undefined;
135
+ /** Only a verified signed audience and matching transport audience can identify a foreign grant. */
136
+ declare function storedDelegationForAnotherKey(entry: unknown, node: RuntimeDelegationActivator): boolean;
137
+ /**
138
+ * Publish a stored CID only when it matches the stored authorization bytes.
139
+ * Free-text and even correctly shaped CIDs of different bytes stay private.
140
+ */
141
+ declare function verifiedStoredCid(node: RuntimeDelegationActivator, entry: unknown): string | undefined;
142
+ /**
143
+ * Replays one stored record under its binding, never installing an unbound or
144
+ * unproven grant. Stored bytes and node messages are never published.
151
145
  */
152
146
  declare function replayStoredDelegation(node: RuntimeDelegationActivator, entry: unknown, options: {
153
147
  readonly host: string;
154
- readonly migrated: boolean;
155
148
  readonly resolveSpace: OperationSpaceResolver;
156
149
  }): Promise<StoredDelegationReplay>;
150
+ type StoredDelegationInspection = {
151
+ readonly local: "verified";
152
+ readonly cid: string;
153
+ readonly effectivePermissions: readonly PermissionEntry[];
154
+ readonly expiry: Date;
155
+ } | {
156
+ readonly local: "refused";
157
+ readonly reason: StoredGrantSkipReason;
158
+ } | {
159
+ readonly local: "not_checked";
160
+ readonly because: "expired" | "no_session";
161
+ };
162
+ /**
163
+ * Checks only local signed bytes, expiry, audience, resources and binding.
164
+ * The node still decides delegation-chain validity and revocation at install.
165
+ */
166
+ declare function inspectStoredDelegation(entry: unknown, options?: {
167
+ readonly node?: RuntimeDelegationActivator;
168
+ readonly host?: string;
169
+ readonly resolveSpace?: OperationSpaceResolver;
170
+ }): Promise<StoredDelegationInspection>;
157
171
  /** An unreadable marker counts as migrated: a damaged marker never reopens migration. */
158
172
  declare function bindingMigrationRecorded(profile: string): Promise<boolean>;
159
173
 
160
- export { BINDING_NOTES, type BindingSource, type StoredDelegationReplay, activateUnboundCompactImport, bindCliGrant, bindingMigrationPath, bindingMigrationRecorded, mergeDelegationsWithoutRequest, operationSpaceResolver, prepareStoredDelegationReplay, replayLimit, replayStoredDelegation, storedDelegationKind };
174
+ export { BINDING_NOTES, type BindingSource, OperationWarning, type StoredDelegationInspection, type StoredDelegationReplay, type StoredDelegationSource, StoredGrantSkipReason, activateUnboundImport, bindCliGrant, bindingMigrationPath, bindingMigrationRecorded, inspectStoredDelegation, mergeDelegationsWithoutRequest, operationSpaceResolver, prepareStoredDelegationReplay, replayLimit, replayProfileDelegations, replayStoredDelegation, storedDelegationForAnotherKey, storedDelegationKind, storedDelegationSource, verifiedCompactAudience, verifiedStoredCid, withoutBearer };
@@ -1,6 +1,7 @@
1
- import { ValidatedRuntimeDelegation, RuntimeDelegationActivator, PortableDelegation, PermissionEntry } from '@tinycloud/node-sdk';
1
+ import { PermissionEntry, ValidatedRuntimeDelegation, RuntimeDelegationActivator, PortableDelegation } from '@tinycloud/node-sdk';
2
2
  import { O as OperationSpaceResolver } from './authority-ofwbEqmj.js';
3
- import { S as StoredGrantSkipReason } from './contract-BRwWJpPs.js';
3
+ import { S as StoredGrantSkipReason, b as OperationWarning } from './contract-DfyrluLB.js';
4
+ export { c as STORED_GRANT_SKIP_REASONS } from './contract-DfyrluLB.js';
4
5
  import '@tinycloud/sdk-core';
5
6
 
6
7
  /** Creates the one owner-aware resolver shared by operation matching paths. */
@@ -25,8 +26,8 @@ declare function operationSpaceResolver(node: unknown, ownerSpace?: string): (sp
25
26
  * signed capabilities (`cli-grant:<cid>`). Their signed-login records carry
26
27
  * the `siweProof` replay verifies them from.
27
28
  *
28
- * Signed-login records the CLI stored before it kept a `siweProof` cannot be
29
- * verified here and keep their legacy CLI replay.
29
+ * Signed-login records the CLI stored without a `siweProof` cannot be
30
+ * verified from signed bytes and are not installed by either runtime.
30
31
  *
31
32
  * The binding is local profile data. It stops records written by any other
32
33
  * path from granting authority. It does not stop someone who can write the
@@ -38,34 +39,21 @@ declare const BINDING_NOTES: Record<BindingSource, string>;
38
39
  /** The per-profile marker: present once that profile's unbound records were migrated. */
39
40
  declare function bindingMigrationPath(profile: string): string;
40
41
  /**
41
- * How replay treats a stored record:
42
+ * Compact and signed-login records require a valid request binding and signed
43
+ * proof. A legacy record with no proof is classified `other` only so replay
44
+ * can report `proof_missing`; it never installs. Malformed headers are refused.
42
45
  *
43
- * - `compact` and `signed-login` records go through validated activation and
44
- * the binding rule.
45
- * - `other` records keep the CLI's legacy replay: an unbound record whose
46
- * bytes are not compact and that has no `siweProof`, which is how earlier
47
- * CLI releases stored their own signed-login grants. The operations runtime
48
- * never installs them.
49
- * - `refused` records install nothing anywhere.
50
- *
51
- * A record is `refused` unless its `delegationHeader` has exactly one own
52
- * key, `Authorization`, with a string value: header names are matched
53
- * case-insensitively on the wire, and other value types are stringified, so
54
- * any other shape could reach the node as authorization bytes this rule never
55
- * read. Bytes containing a `.` are never `other`: a CACAO has none, and
56
- * validated activation refuses anything compact-shaped that it cannot parse.
57
- * A record with an `authorityRequest` (valid or not) is never `other`: the
58
- * legacy path cannot hold it to a binding, so dropping a `siweProof` cannot
59
- * route a bound signed-login delegation around its binding.
46
+ * A header must contain exactly one `Authorization` string key: other shapes
47
+ * might reach the node as authorization bytes this rule never examined.
60
48
  */
61
49
  declare function storedDelegationKind(entry: unknown): "compact" | "signed-login" | "other" | "refused";
62
- /**
63
- * What replay holds a stored record to: its binding's `requested`, `"signed"`
64
- * for an unbound compact record before the profile has migrated (it installs
65
- * with its own signed authority, as before bindings existed), or `undefined`
66
- * when the record installs nothing.
67
- */
68
- declare function replayLimit(entry: unknown, migrated: boolean): readonly PermissionEntry[] | "signed" | undefined;
50
+ /** A record replays only within a valid stored request binding. */
51
+ declare function replayLimit(entry: unknown): readonly PermissionEntry[] | undefined;
52
+ /** Match node-sdk's normalization before validating a compact signature. */
53
+ declare function withoutBearer(authorization: string): string;
54
+ type StoredDelegationSource = "cli-grant" | "unbound-import" | "migration" | "request" | "legacy" | "unknown";
55
+ /** Constrained labels only; never publish untrusted request IDs or audit notes. */
56
+ declare function storedDelegationSource(entry: unknown): StoredDelegationSource;
69
57
  /**
70
58
  * Binds the record of one of the CLI's own grants, already checked against
71
59
  * the request it answers, to exactly the capabilities its signed bytes grant.
@@ -77,12 +65,10 @@ declare function bindCliGrant<T extends {
77
65
  readonly delegation: PortableDelegation;
78
66
  }>(node: RuntimeDelegationActivator, record: T, host: string): Promise<T & Record<"authorityRequest" | "authorityRequestAudit", unknown>>;
79
67
  /**
80
- * Validates and activates a compact delegation that `tc auth import` received
81
- * without a stored request, through the same validated activation replay uses,
82
- * and returns its record bound to exactly the capabilities its signed bytes
83
- * grant. Throws when validation or activation fails.
68
+ * Validates and activates an imported compact or signed-login delegation,
69
+ * binding its record to exactly its verified signed capabilities.
84
70
  */
85
- declare function activateUnboundCompactImport(node: RuntimeDelegationActivator, delegation: PortableDelegation, host: string): Promise<{
71
+ declare function activateUnboundImport(node: RuntimeDelegationActivator, delegation: PortableDelegation, host: string): Promise<{
86
72
  delegation: PortableDelegation;
87
73
  permissions: PermissionEntry[];
88
74
  } & Record<string, unknown>>;
@@ -100,26 +86,18 @@ declare function mergeDelegationsWithoutRequest(stored: readonly unknown[], inco
100
86
  };
101
87
  } & Record<string, unknown>)[]): unknown[];
102
88
  /**
103
- * Runs before replay reads the profile's records, so those records and the
104
- * migration marker agree. Returns whether the profile has migrated.
89
+ * Runs migration before replay reads the profile's records. Returns whether
90
+ * the marker exists; replay refuses unbound records either way.
105
91
  *
106
- * Migration runs under the profile lock, and only while the profile's
107
- * persisted session is still the one `node` restored: a session rotated since
108
- * the restore leaves migration to a runtime of the new session. Each compact
109
- * record with no `authorityRequest` is handled on its own: if validated
110
- * activation can read its signed capabilities (CID, expiry, audience and
111
- * declared resources checked, nothing activated) and they form a valid
112
- * binding, the record is bound to exactly those capabilities; otherwise it
113
- * stays unbound, is listed in the marker's `unbound`, and installs nothing
114
- * after migration. A compact record whose capabilities cannot be read could
115
- * not activate for this session either. `migrate` must be false unless `node`
92
+ * Migration runs under the profile lock, and only while the persisted session
93
+ * is still the one `node` restored. Each unbound compact record is checked
94
+ * without activation and bound to exactly its signed capabilities, or left
95
+ * unbound when validation fails. `migrate` must be false unless the node
116
96
  * holds the profile's own restored session.
117
97
  *
118
- * Migration is best-effort and restartable. The bound records are written
119
- * first and the marker last; a busy lock or any failure before the marker
120
- * leaves the profile unmigrated, so this runtime replays under the
121
- * pre-migration rule and the next one migrates again. Records already bound
122
- * by an interrupted run keep their bindings.
98
+ * Migration is best-effort and restartable. Bound records are written before
99
+ * the marker; a busy lock or failure leaves migration for a later runtime.
100
+ * Records already bound by an interrupted run keep their bindings.
123
101
  */
124
102
  declare function prepareStoredDelegationReplay(profile: string, node: RuntimeDelegationActivator, options: {
125
103
  readonly host: string;
@@ -140,21 +118,57 @@ type StoredDelegationReplay = {
140
118
  readonly status: "not-replayed";
141
119
  };
142
120
  /**
143
- * Replays one stored record under the binding rule. A record with a valid
144
- * binding installs only if its signed capabilities fit inside it. Before the
145
- * profile has migrated, an unbound compact record installs with its signed
146
- * authority as it always did; after, it installs nothing. A signed-login
147
- * record installs only with a binding. A record with neither compact bytes
148
- * nor a `siweProof` cannot be verified here and installs nothing. Never
149
- * throws, and never reports exception text: stored data is untrusted
150
- * transport material, and messages can quote it or a node's response.
121
+ * The single stored-grant replay path for CLI and canonical runtimes.
122
+ * Migration runs before the store read; CID deduplication affects authority
123
+ * only, not the per-record fixed-code skip diagnostics.
124
+ */
125
+ declare function replayProfileDelegations(profile: string, node: RuntimeDelegationActivator, options: {
126
+ readonly host: string;
127
+ readonly migrate: boolean;
128
+ readonly resolveSpace: OperationSpaceResolver;
129
+ }): Promise<{
130
+ installed: ValidatedRuntimeDelegation[];
131
+ warnings: OperationWarning[];
132
+ }>;
133
+ /** Return an audience only after the exact compact bytes, CID and signature verify. */
134
+ declare function verifiedCompactAudience(node: RuntimeDelegationActivator, delegation: PortableDelegation): string | undefined;
135
+ /** Only a verified signed audience and matching transport audience can identify a foreign grant. */
136
+ declare function storedDelegationForAnotherKey(entry: unknown, node: RuntimeDelegationActivator): boolean;
137
+ /**
138
+ * Publish a stored CID only when it matches the stored authorization bytes.
139
+ * Free-text and even correctly shaped CIDs of different bytes stay private.
140
+ */
141
+ declare function verifiedStoredCid(node: RuntimeDelegationActivator, entry: unknown): string | undefined;
142
+ /**
143
+ * Replays one stored record under its binding, never installing an unbound or
144
+ * unproven grant. Stored bytes and node messages are never published.
151
145
  */
152
146
  declare function replayStoredDelegation(node: RuntimeDelegationActivator, entry: unknown, options: {
153
147
  readonly host: string;
154
- readonly migrated: boolean;
155
148
  readonly resolveSpace: OperationSpaceResolver;
156
149
  }): Promise<StoredDelegationReplay>;
150
+ type StoredDelegationInspection = {
151
+ readonly local: "verified";
152
+ readonly cid: string;
153
+ readonly effectivePermissions: readonly PermissionEntry[];
154
+ readonly expiry: Date;
155
+ } | {
156
+ readonly local: "refused";
157
+ readonly reason: StoredGrantSkipReason;
158
+ } | {
159
+ readonly local: "not_checked";
160
+ readonly because: "expired" | "no_session";
161
+ };
162
+ /**
163
+ * Checks only local signed bytes, expiry, audience, resources and binding.
164
+ * The node still decides delegation-chain validity and revocation at install.
165
+ */
166
+ declare function inspectStoredDelegation(entry: unknown, options?: {
167
+ readonly node?: RuntimeDelegationActivator;
168
+ readonly host?: string;
169
+ readonly resolveSpace?: OperationSpaceResolver;
170
+ }): Promise<StoredDelegationInspection>;
157
171
  /** An unreadable marker counts as migrated: a damaged marker never reopens migration. */
158
172
  declare function bindingMigrationRecorded(profile: string): Promise<boolean>;
159
173
 
160
- export { BINDING_NOTES, type BindingSource, type StoredDelegationReplay, activateUnboundCompactImport, bindCliGrant, bindingMigrationPath, bindingMigrationRecorded, mergeDelegationsWithoutRequest, operationSpaceResolver, prepareStoredDelegationReplay, replayLimit, replayStoredDelegation, storedDelegationKind };
174
+ export { BINDING_NOTES, type BindingSource, OperationWarning, type StoredDelegationInspection, type StoredDelegationReplay, type StoredDelegationSource, StoredGrantSkipReason, activateUnboundImport, bindCliGrant, bindingMigrationPath, bindingMigrationRecorded, inspectStoredDelegation, mergeDelegationsWithoutRequest, operationSpaceResolver, prepareStoredDelegationReplay, replayLimit, replayProfileDelegations, replayStoredDelegation, storedDelegationForAnotherKey, storedDelegationKind, storedDelegationSource, verifiedCompactAudience, verifiedStoredCid, withoutBearer };