@inixiative/signet 0.3.0 → 0.4.0

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
@@ -10,17 +10,21 @@ This package is the one implementation of that protocol, shared by Kingdom (whic
10
10
  - `proof`: create and verify DPoP proofs (ES256, nonce-bound, access-token-bound).
11
11
  - `files`: private 0600 JSON files for keys and credentials.
12
12
  - `client`:
13
- - an **Installation** (a local Foundry, Archive or Oracle) is an actor known to Kingdom by its key: `registerInstallation`, then `requestRegistration` returns a review code a person claims in Kingdom (a `registerIntegration` Inquiry), then `collectSignet` and `saveCollectedSignet`. `installationInquiries`, `installationSignets`, `cancelInstallationInquiry`, `enrollInstallationSignet` and `rotateInstallationKey` act as the installation;
13
+ - an **Installation** (a local Foundry, Archive or Oracle) is an actor known to Kingdom by its key: `registerInstallation`, then `requestRegistration` asks for what it needs (the owner it expects, by organization id or slug, and resources by id or by kind and name, with their operations) and returns a review code a person claims in Kingdom (a `registerIntegration` Inquiry), where the review opens with that owner and those resources selected, then `collectSignet` and `saveCollectedSignet`. `installationInquiries`, `installationSignets`, `cancelInstallationInquiry`, `enrollInstallationSignet` and `rotateInstallationKey` act as the installation;
14
14
  - `pairInstallation` does the whole pairing (register, request, wait on the socket, confirm the owner, collect) and `holdInstallationSignets` keeps one credential file per Signet the installation's integrations hold, enrolling later grants and dropping revoked ones;
15
15
  - `InstallationSocket`, Kingdom's live line to an installation: it proves the key, receives a snapshot of the installation's inquiries and Signets on connect and on every change, keeps the installation's integrations marked online, advertises its viewer URL, and polls the same reads while the socket is down;
16
- - `SignetClient`, which renews its access token and signs each call: `describe`, `execute`, task settlement, and the run actions a Foundry uses for inference (`resolveRun`, `delegateRun`, `renewRun`, `revokeRun`).
16
+ - `SignetClient`, which renews its access token and signs each call: `describe`, `execute`, task settlement, and the run actions a Foundry uses for inference (`resolveRun`, `delegateRun`, `renewRun`, `revokeRun`), and for a subscription run `releaseSubscription` and `reportSubscriptionLimits`.
17
17
 
18
18
  ```ts
19
19
  import { holdInstallationSignets, InstallationSocket, pairInstallation, SignetClient } from '@inixiative/signet';
20
20
 
21
21
  const paired = await pairInstallation({
22
22
  url: kingdom, root: dataDir, kind: 'archive', name: 'Laptop Archive', sourceId,
23
- terms: { name: 'Laptop Archive', lifecycle: 'ongoing', resources: [], expiresAt: null, maxRequests: null, maxConcurrent: 4 },
23
+ terms: {
24
+ name: 'Laptop Archive', lifecycle: 'ongoing', expiresAt: null, maxRequests: null, maxConcurrent: 4,
25
+ owner: { ownerModel: 'Organization', organization: 'inixiative' },
26
+ resources: [{ resourceKind: 'archiveLibrary', operations: ['sessions.write'] }],
27
+ },
24
28
  onReview: ({ review }) => console.log(`Approve in Kingdom: ${review}`),
25
29
  confirmOwner: async ({ ownerName }) => confirm(`Pair with ${ownerName}?`),
26
30
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inixiative/signet",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Present Kingdom Signets: the wire contracts, DPoP proofs, device pairing and a renewing client shared by Kingdom, Archive, Foundry and Oracle.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "devDependencies": {
36
36
  "@biomejs/biome": "2.5.2",
37
- "@inixiative/config": "^0.5.59",
37
+ "@inixiative/config": "^0.5.78",
38
38
  "@types/bun": "1.4.2",
39
39
  "lefthook": "2.1.9",
40
40
  "typescript": "6.0.3",
package/src/client.ts CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  nonceSchema,
13
13
  ownerRefSchema,
14
14
  publicClientKeySchema,
15
- type RegistrationTerms,
15
+ type RegistrationRequest,
16
16
  registerInstallationResponseSchema,
17
17
  renewalCredentialPattern,
18
18
  requestRegistrationResponseSchema,
@@ -249,7 +249,7 @@ export const registerInstallation = (
249
249
  export const requestRegistration = (
250
250
  url: string,
251
251
  keyFile: string,
252
- terms: RegistrationTerms,
252
+ terms: RegistrationRequest,
253
253
  options: SignetRequestOptions = {},
254
254
  ) =>
255
255
  installationPost(
@@ -411,7 +411,9 @@ export type SignetAction =
411
411
  | 'resolveRun'
412
412
  | 'delegateRun'
413
413
  | 'renewRun'
414
- | 'revokeRun';
414
+ | 'revokeRun'
415
+ | 'releaseSubscription'
416
+ | 'reportSubscriptionLimits';
415
417
  const signetActions: SignetAction[] = [
416
418
  'describe',
417
419
  'execute',
@@ -422,6 +424,8 @@ const signetActions: SignetAction[] = [
422
424
  'delegateRun',
423
425
  'renewRun',
424
426
  'revokeRun',
427
+ 'releaseSubscription',
428
+ 'reportSubscriptionLimits',
425
429
  ];
426
430
 
427
431
  /** Presents one enrolled Signet: renews its access token and signs each call with the device key. */
package/src/contracts.ts CHANGED
@@ -104,12 +104,33 @@ export const signetReviewProposalSchema = z.strictObject({
104
104
  ...signetTerms,
105
105
  resources: z.array(signetResourceSchema).max(100),
106
106
  });
107
- /** What an Installation asks for when it asks to be registered as an owner's integration. */
107
+ /** The terms a person approves when registering an Installation as an owner's integration. */
108
108
  export const registrationTermsSchema = z.strictObject({
109
109
  ...signetTerms,
110
110
  lifecycle: z.literal('ongoing'),
111
111
  resources: z.array(signetResourceSchema).max(100),
112
112
  });
113
+ /** The owner an Installation asks to belong to; `organization` is the organization's id or slug. */
114
+ export const requestedOwnerSchema = z.strictObject({
115
+ ownerModel: ownerModelSchema,
116
+ organization: z.string().trim().min(1).max(120).optional(),
117
+ spaceId: z.uuid().optional(),
118
+ });
119
+ /** A resource asked for by kind, and optionally name, when the Installation does not know its id. */
120
+ export const requestedResourceKindSchema = z.strictObject({
121
+ resourceKind: z.string().min(1).max(80),
122
+ resourceName: z.string().trim().min(1).max(120).optional(),
123
+ operations: z.array(z.string().min(1).max(80)).min(1).max(100),
124
+ lens: signetLensSchema.default({}),
125
+ });
126
+ export const requestedResourceSchema = z.union([signetResourceSchema, requestedResourceKindSchema]);
127
+ /** What an Installation asks for: the owner it expects and the resources and operations it needs. */
128
+ export const registrationRequestSchema = z.strictObject({
129
+ ...signetTerms,
130
+ lifecycle: z.literal('ongoing'),
131
+ owner: requestedOwnerSchema.optional(),
132
+ resources: z.array(requestedResourceSchema).max(100),
133
+ });
113
134
  /** A person asks for a Signet on an integration, to be presented with `publicKey`. */
114
135
  export const signetRequestSchema = z.strictObject({
115
136
  ...signetTerms,
@@ -124,6 +145,9 @@ export const signetRequestResponseSchema = z.object({
124
145
  });
125
146
  export type SignetProposal = z.infer<typeof signetProposalSchema>;
126
147
  export type RegistrationTerms = z.infer<typeof registrationTermsSchema>;
148
+ export type RequestedOwner = z.infer<typeof requestedOwnerSchema>;
149
+ export type RequestedResource = z.input<typeof requestedResourceSchema>;
150
+ export type RegistrationRequest = z.input<typeof registrationRequestSchema>;
127
151
  export type SignetRequest = z.infer<typeof signetRequestSchema>;
128
152
  export type SignetRequestResponse = z.infer<typeof signetRequestResponseSchema>;
129
153
 
@@ -139,7 +163,7 @@ export const registerInstallationSchema = z
139
163
  message: 'A local Archive registers with its sourceId',
140
164
  });
141
165
  export const registerInstallationResponseSchema = z.object({ installationId: z.uuid() });
142
- export const requestRegistrationSchema = z.strictObject({ terms: registrationTermsSchema });
166
+ export const requestRegistrationSchema = z.strictObject({ terms: registrationRequestSchema });
143
167
  export const requestRegistrationResponseSchema = z.object({
144
168
  reviewCode: z.string(),
145
169
  expiresAt: z.iso.datetime(),
@@ -12,7 +12,7 @@ import {
12
12
  saveCollectedSignet,
13
13
  signetCredentialSchema,
14
14
  } from './client';
15
- import type { InstallationKind, OwnerRef, RegistrationTerms } from './contracts';
15
+ import type { InstallationKind, OwnerRef, RegistrationRequest } from './contracts';
16
16
  import { readPrivateJson, writePrivateJson } from './files';
17
17
  import { type InstallationSnapshot, InstallationSocket } from './installationSocket';
18
18
 
@@ -109,7 +109,7 @@ export type InstallationPairing = {
109
109
  kind: InstallationKind;
110
110
  name: string;
111
111
  sourceId?: string;
112
- terms: RegistrationTerms;
112
+ terms: RegistrationRequest;
113
113
  onReview: (review: { reviewCode: string; review: string; expiresAt: string }) => void;
114
114
  confirmOwner?: (owner: { ownerName: string | null; owner: OwnerRef | null }) => Promise<boolean>;
115
115
  /** Failures while waiting (a poll Kingdom refused, a dropped socket); waiting continues. */