@tinycloud/operations 0.3.4-beta.6 → 0.4.0-beta.8
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/artifacts.cjs +416 -50
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +115 -58
- package/dist/artifacts.d.ts +115 -58
- package/dist/artifacts.js +417 -50
- package/dist/artifacts.js.map +1 -1
- package/dist/authority-ofwbEqmj.d.cts +30 -0
- package/dist/authority-ofwbEqmj.d.ts +30 -0
- package/dist/cli-runtime.cjs +652 -120
- package/dist/cli-runtime.cjs.map +1 -1
- package/dist/cli-runtime.js +645 -116
- package/dist/cli-runtime.js.map +1 -1
- package/dist/delegation-binding.cjs +7956 -0
- package/dist/delegation-binding.cjs.map +1 -0
- package/dist/delegation-binding.d.cts +130 -0
- package/dist/delegation-binding.d.ts +130 -0
- package/dist/delegation-binding.js +7948 -0
- package/dist/delegation-binding.js.map +1 -0
- package/dist/index.cjs +649 -117
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +645 -116
- package/dist/index.js.map +1 -1
- package/dist/profile.cjs +9 -2
- package/dist/profile.cjs.map +1 -1
- package/dist/profile.js +11 -2
- package/dist/profile.js.map +1 -1
- package/dist/state.cjs +426 -50
- package/dist/state.cjs.map +1 -1
- package/dist/state.d.cts +38 -5
- package/dist/state.d.ts +38 -5
- package/dist/state.js +424 -50
- package/dist/state.js.map +1 -1
- package/generated/operations.json +8 -4
- package/package.json +8 -3
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { RuntimeDelegationActivator, PortableDelegation, PermissionEntry, ValidatedRuntimeDelegation } from '@tinycloud/node-sdk';
|
|
2
|
+
import { O as OperationSpaceResolver } from './authority-ofwbEqmj.cjs';
|
|
3
|
+
import '@tinycloud/sdk-core';
|
|
4
|
+
|
|
5
|
+
/** Creates the one owner-aware resolver shared by operation matching paths. */
|
|
6
|
+
declare function operationSpaceResolver(node: unknown, ownerSpace?: string): (space: string) => string;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Request bindings for delegations stored in `additional-delegations.json`.
|
|
10
|
+
*
|
|
11
|
+
* A compact-UCAN or signed-login (SIWE) record replays only when its
|
|
12
|
+
* `authorityRequest` binding is valid and the capabilities its signed bytes
|
|
13
|
+
* grant fit inside the binding's `requested`. Validated activation checks that
|
|
14
|
+
* before anything is activated. Three writers produce bindings:
|
|
15
|
+
*
|
|
16
|
+
* - `tinycloud.auth.import`: the stored request the delegation was checked
|
|
17
|
+
* against (`requestId` is that request's).
|
|
18
|
+
* - `tc auth import` of an artifact with no request: exactly the delegation's
|
|
19
|
+
* own signed capabilities (`unbound-import:<cid>`).
|
|
20
|
+
* - The one-time migration of records stored before bindings existed: exactly
|
|
21
|
+
* each record's own signed capabilities (`migrated:<cid>`).
|
|
22
|
+
*
|
|
23
|
+
* Records the CLI stores from its own signed-login grants carry no
|
|
24
|
+
* `siweProof`, cannot be verified here, and keep their legacy CLI replay.
|
|
25
|
+
*
|
|
26
|
+
* The binding is local profile data. It stops records written by any other
|
|
27
|
+
* path from granting authority. It does not stop someone who can write the
|
|
28
|
+
* profile directory, who already holds the session key and the signed bytes.
|
|
29
|
+
*/
|
|
30
|
+
type BindingSource = "migration" | "unbound-import";
|
|
31
|
+
/** The audit note written beside a binding synthesized from a record's own signed capabilities. */
|
|
32
|
+
declare const BINDING_NOTES: Record<BindingSource, string>;
|
|
33
|
+
/** The per-profile marker: present once that profile's unbound records were migrated. */
|
|
34
|
+
declare function bindingMigrationPath(profile: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* How replay treats a stored record:
|
|
37
|
+
*
|
|
38
|
+
* - `compact` and `signed-login` records go through validated activation and
|
|
39
|
+
* the binding rule.
|
|
40
|
+
* - `other` records keep the CLI's legacy replay: an unbound record whose
|
|
41
|
+
* bytes are not compact and that has no `siweProof`, which is how the CLI
|
|
42
|
+
* stores its own signed-login grants. The operations runtime never installs
|
|
43
|
+
* them.
|
|
44
|
+
* - `refused` records install nothing anywhere.
|
|
45
|
+
*
|
|
46
|
+
* A record is `refused` unless its `delegationHeader` has exactly one own
|
|
47
|
+
* key, `Authorization`, with a string value: header names are matched
|
|
48
|
+
* case-insensitively on the wire, and other value types are stringified, so
|
|
49
|
+
* any other shape could reach the node as authorization bytes this rule never
|
|
50
|
+
* read. Bytes containing a `.` are never `other`: a CACAO has none, and
|
|
51
|
+
* validated activation refuses anything compact-shaped that it cannot parse.
|
|
52
|
+
* A record with an `authorityRequest` (valid or not) is never `other`: the
|
|
53
|
+
* legacy path cannot hold it to a binding, so dropping a `siweProof` cannot
|
|
54
|
+
* route a bound signed-login delegation around its binding.
|
|
55
|
+
*/
|
|
56
|
+
declare function storedDelegationKind(entry: unknown): "compact" | "signed-login" | "other" | "refused";
|
|
57
|
+
/**
|
|
58
|
+
* What replay holds a stored record to: its binding's `requested`, `"signed"`
|
|
59
|
+
* for an unbound compact record before the profile has migrated (it installs
|
|
60
|
+
* with its own signed authority, as before bindings existed), or `undefined`
|
|
61
|
+
* when the record installs nothing.
|
|
62
|
+
*/
|
|
63
|
+
declare function replayLimit(entry: unknown, migrated: boolean): readonly PermissionEntry[] | "signed" | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Validates and activates a compact delegation that `tc auth import` received
|
|
66
|
+
* without a stored request, through the same validated activation replay uses,
|
|
67
|
+
* and returns its record bound to exactly the capabilities its signed bytes
|
|
68
|
+
* grant. Throws when validation or activation fails.
|
|
69
|
+
*/
|
|
70
|
+
declare function activateUnboundCompactImport(node: RuntimeDelegationActivator, delegation: PortableDelegation, host: string): Promise<{
|
|
71
|
+
delegation: PortableDelegation;
|
|
72
|
+
permissions: PermissionEntry[];
|
|
73
|
+
} & Record<string, unknown>>;
|
|
74
|
+
/**
|
|
75
|
+
* The stored records after adding records written without a stored request
|
|
76
|
+
* (by `tc auth import` or a CLI grant). A stored record for the same CID that
|
|
77
|
+
* carries an `authorityRequest` is kept as it is, so this route never drops,
|
|
78
|
+
* replaces or weakens a binding; otherwise each record replaces every row for
|
|
79
|
+
* its CID, at the first one's position, or is appended. Callers write the
|
|
80
|
+
* result under the profile lock they already use for this store.
|
|
81
|
+
*/
|
|
82
|
+
declare function mergeDelegationsWithoutRequest(stored: readonly unknown[], incoming: readonly ({
|
|
83
|
+
readonly delegation: {
|
|
84
|
+
readonly cid: string;
|
|
85
|
+
};
|
|
86
|
+
} & Record<string, unknown>)[]): unknown[];
|
|
87
|
+
/**
|
|
88
|
+
* Runs before replay reads the profile's records, so those records and the
|
|
89
|
+
* migration marker agree. Returns whether the profile has migrated.
|
|
90
|
+
*
|
|
91
|
+
* Migration runs under the profile lock, and only while the profile's
|
|
92
|
+
* persisted session is still the one `node` restored: a session rotated since
|
|
93
|
+
* the restore leaves migration to a runtime of the new session. Each compact
|
|
94
|
+
* record with no `authorityRequest` is handled on its own: if validated
|
|
95
|
+
* activation can read its signed capabilities (CID, expiry, audience and
|
|
96
|
+
* declared resources checked, nothing activated) and they form a valid
|
|
97
|
+
* binding, the record is bound to exactly those capabilities; otherwise it
|
|
98
|
+
* stays unbound, is listed in the marker's `unbound`, and installs nothing
|
|
99
|
+
* after migration. A compact record whose capabilities cannot be read could
|
|
100
|
+
* not activate for this session either. `migrate` must be false unless `node`
|
|
101
|
+
* holds the profile's own restored session.
|
|
102
|
+
*
|
|
103
|
+
* Migration is best-effort and restartable. The bound records are written
|
|
104
|
+
* first and the marker last; a busy lock or any failure before the marker
|
|
105
|
+
* leaves the profile unmigrated, so this runtime replays under the
|
|
106
|
+
* pre-migration rule and the next one migrates again. Records already bound
|
|
107
|
+
* by an interrupted run keep their bindings.
|
|
108
|
+
*/
|
|
109
|
+
declare function prepareStoredDelegationReplay(profile: string, node: RuntimeDelegationActivator, options: {
|
|
110
|
+
readonly host: string;
|
|
111
|
+
readonly migrate: boolean;
|
|
112
|
+
}): Promise<boolean>;
|
|
113
|
+
/**
|
|
114
|
+
* Replays one stored record under the binding rule. A record with a valid
|
|
115
|
+
* binding installs only if its signed capabilities fit inside it. Before the
|
|
116
|
+
* profile has migrated, an unbound compact record installs with its signed
|
|
117
|
+
* authority as it always did; after, it installs nothing. A signed-login
|
|
118
|
+
* record installs only with a binding. Returns the installed delegation, or
|
|
119
|
+
* `undefined` when the record installs nothing. Never throws: stored data is
|
|
120
|
+
* untrusted transport material.
|
|
121
|
+
*/
|
|
122
|
+
declare function replayStoredDelegation(node: RuntimeDelegationActivator, entry: unknown, options: {
|
|
123
|
+
readonly host: string;
|
|
124
|
+
readonly migrated: boolean;
|
|
125
|
+
readonly resolveSpace: OperationSpaceResolver;
|
|
126
|
+
}): Promise<ValidatedRuntimeDelegation | undefined>;
|
|
127
|
+
/** An unreadable marker counts as migrated: a damaged marker never reopens migration. */
|
|
128
|
+
declare function bindingMigrationRecorded(profile: string): Promise<boolean>;
|
|
129
|
+
|
|
130
|
+
export { BINDING_NOTES, type BindingSource, activateUnboundCompactImport, bindingMigrationPath, bindingMigrationRecorded, mergeDelegationsWithoutRequest, operationSpaceResolver, prepareStoredDelegationReplay, replayLimit, replayStoredDelegation, storedDelegationKind };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { RuntimeDelegationActivator, PortableDelegation, PermissionEntry, ValidatedRuntimeDelegation } from '@tinycloud/node-sdk';
|
|
2
|
+
import { O as OperationSpaceResolver } from './authority-ofwbEqmj.js';
|
|
3
|
+
import '@tinycloud/sdk-core';
|
|
4
|
+
|
|
5
|
+
/** Creates the one owner-aware resolver shared by operation matching paths. */
|
|
6
|
+
declare function operationSpaceResolver(node: unknown, ownerSpace?: string): (space: string) => string;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Request bindings for delegations stored in `additional-delegations.json`.
|
|
10
|
+
*
|
|
11
|
+
* A compact-UCAN or signed-login (SIWE) record replays only when its
|
|
12
|
+
* `authorityRequest` binding is valid and the capabilities its signed bytes
|
|
13
|
+
* grant fit inside the binding's `requested`. Validated activation checks that
|
|
14
|
+
* before anything is activated. Three writers produce bindings:
|
|
15
|
+
*
|
|
16
|
+
* - `tinycloud.auth.import`: the stored request the delegation was checked
|
|
17
|
+
* against (`requestId` is that request's).
|
|
18
|
+
* - `tc auth import` of an artifact with no request: exactly the delegation's
|
|
19
|
+
* own signed capabilities (`unbound-import:<cid>`).
|
|
20
|
+
* - The one-time migration of records stored before bindings existed: exactly
|
|
21
|
+
* each record's own signed capabilities (`migrated:<cid>`).
|
|
22
|
+
*
|
|
23
|
+
* Records the CLI stores from its own signed-login grants carry no
|
|
24
|
+
* `siweProof`, cannot be verified here, and keep their legacy CLI replay.
|
|
25
|
+
*
|
|
26
|
+
* The binding is local profile data. It stops records written by any other
|
|
27
|
+
* path from granting authority. It does not stop someone who can write the
|
|
28
|
+
* profile directory, who already holds the session key and the signed bytes.
|
|
29
|
+
*/
|
|
30
|
+
type BindingSource = "migration" | "unbound-import";
|
|
31
|
+
/** The audit note written beside a binding synthesized from a record's own signed capabilities. */
|
|
32
|
+
declare const BINDING_NOTES: Record<BindingSource, string>;
|
|
33
|
+
/** The per-profile marker: present once that profile's unbound records were migrated. */
|
|
34
|
+
declare function bindingMigrationPath(profile: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* How replay treats a stored record:
|
|
37
|
+
*
|
|
38
|
+
* - `compact` and `signed-login` records go through validated activation and
|
|
39
|
+
* the binding rule.
|
|
40
|
+
* - `other` records keep the CLI's legacy replay: an unbound record whose
|
|
41
|
+
* bytes are not compact and that has no `siweProof`, which is how the CLI
|
|
42
|
+
* stores its own signed-login grants. The operations runtime never installs
|
|
43
|
+
* them.
|
|
44
|
+
* - `refused` records install nothing anywhere.
|
|
45
|
+
*
|
|
46
|
+
* A record is `refused` unless its `delegationHeader` has exactly one own
|
|
47
|
+
* key, `Authorization`, with a string value: header names are matched
|
|
48
|
+
* case-insensitively on the wire, and other value types are stringified, so
|
|
49
|
+
* any other shape could reach the node as authorization bytes this rule never
|
|
50
|
+
* read. Bytes containing a `.` are never `other`: a CACAO has none, and
|
|
51
|
+
* validated activation refuses anything compact-shaped that it cannot parse.
|
|
52
|
+
* A record with an `authorityRequest` (valid or not) is never `other`: the
|
|
53
|
+
* legacy path cannot hold it to a binding, so dropping a `siweProof` cannot
|
|
54
|
+
* route a bound signed-login delegation around its binding.
|
|
55
|
+
*/
|
|
56
|
+
declare function storedDelegationKind(entry: unknown): "compact" | "signed-login" | "other" | "refused";
|
|
57
|
+
/**
|
|
58
|
+
* What replay holds a stored record to: its binding's `requested`, `"signed"`
|
|
59
|
+
* for an unbound compact record before the profile has migrated (it installs
|
|
60
|
+
* with its own signed authority, as before bindings existed), or `undefined`
|
|
61
|
+
* when the record installs nothing.
|
|
62
|
+
*/
|
|
63
|
+
declare function replayLimit(entry: unknown, migrated: boolean): readonly PermissionEntry[] | "signed" | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Validates and activates a compact delegation that `tc auth import` received
|
|
66
|
+
* without a stored request, through the same validated activation replay uses,
|
|
67
|
+
* and returns its record bound to exactly the capabilities its signed bytes
|
|
68
|
+
* grant. Throws when validation or activation fails.
|
|
69
|
+
*/
|
|
70
|
+
declare function activateUnboundCompactImport(node: RuntimeDelegationActivator, delegation: PortableDelegation, host: string): Promise<{
|
|
71
|
+
delegation: PortableDelegation;
|
|
72
|
+
permissions: PermissionEntry[];
|
|
73
|
+
} & Record<string, unknown>>;
|
|
74
|
+
/**
|
|
75
|
+
* The stored records after adding records written without a stored request
|
|
76
|
+
* (by `tc auth import` or a CLI grant). A stored record for the same CID that
|
|
77
|
+
* carries an `authorityRequest` is kept as it is, so this route never drops,
|
|
78
|
+
* replaces or weakens a binding; otherwise each record replaces every row for
|
|
79
|
+
* its CID, at the first one's position, or is appended. Callers write the
|
|
80
|
+
* result under the profile lock they already use for this store.
|
|
81
|
+
*/
|
|
82
|
+
declare function mergeDelegationsWithoutRequest(stored: readonly unknown[], incoming: readonly ({
|
|
83
|
+
readonly delegation: {
|
|
84
|
+
readonly cid: string;
|
|
85
|
+
};
|
|
86
|
+
} & Record<string, unknown>)[]): unknown[];
|
|
87
|
+
/**
|
|
88
|
+
* Runs before replay reads the profile's records, so those records and the
|
|
89
|
+
* migration marker agree. Returns whether the profile has migrated.
|
|
90
|
+
*
|
|
91
|
+
* Migration runs under the profile lock, and only while the profile's
|
|
92
|
+
* persisted session is still the one `node` restored: a session rotated since
|
|
93
|
+
* the restore leaves migration to a runtime of the new session. Each compact
|
|
94
|
+
* record with no `authorityRequest` is handled on its own: if validated
|
|
95
|
+
* activation can read its signed capabilities (CID, expiry, audience and
|
|
96
|
+
* declared resources checked, nothing activated) and they form a valid
|
|
97
|
+
* binding, the record is bound to exactly those capabilities; otherwise it
|
|
98
|
+
* stays unbound, is listed in the marker's `unbound`, and installs nothing
|
|
99
|
+
* after migration. A compact record whose capabilities cannot be read could
|
|
100
|
+
* not activate for this session either. `migrate` must be false unless `node`
|
|
101
|
+
* holds the profile's own restored session.
|
|
102
|
+
*
|
|
103
|
+
* Migration is best-effort and restartable. The bound records are written
|
|
104
|
+
* first and the marker last; a busy lock or any failure before the marker
|
|
105
|
+
* leaves the profile unmigrated, so this runtime replays under the
|
|
106
|
+
* pre-migration rule and the next one migrates again. Records already bound
|
|
107
|
+
* by an interrupted run keep their bindings.
|
|
108
|
+
*/
|
|
109
|
+
declare function prepareStoredDelegationReplay(profile: string, node: RuntimeDelegationActivator, options: {
|
|
110
|
+
readonly host: string;
|
|
111
|
+
readonly migrate: boolean;
|
|
112
|
+
}): Promise<boolean>;
|
|
113
|
+
/**
|
|
114
|
+
* Replays one stored record under the binding rule. A record with a valid
|
|
115
|
+
* binding installs only if its signed capabilities fit inside it. Before the
|
|
116
|
+
* profile has migrated, an unbound compact record installs with its signed
|
|
117
|
+
* authority as it always did; after, it installs nothing. A signed-login
|
|
118
|
+
* record installs only with a binding. Returns the installed delegation, or
|
|
119
|
+
* `undefined` when the record installs nothing. Never throws: stored data is
|
|
120
|
+
* untrusted transport material.
|
|
121
|
+
*/
|
|
122
|
+
declare function replayStoredDelegation(node: RuntimeDelegationActivator, entry: unknown, options: {
|
|
123
|
+
readonly host: string;
|
|
124
|
+
readonly migrated: boolean;
|
|
125
|
+
readonly resolveSpace: OperationSpaceResolver;
|
|
126
|
+
}): Promise<ValidatedRuntimeDelegation | undefined>;
|
|
127
|
+
/** An unreadable marker counts as migrated: a damaged marker never reopens migration. */
|
|
128
|
+
declare function bindingMigrationRecorded(profile: string): Promise<boolean>;
|
|
129
|
+
|
|
130
|
+
export { BINDING_NOTES, type BindingSource, activateUnboundCompactImport, bindingMigrationPath, bindingMigrationRecorded, mergeDelegationsWithoutRequest, operationSpaceResolver, prepareStoredDelegationReplay, replayLimit, replayStoredDelegation, storedDelegationKind };
|