@pidgeon-ai/issuer 0.1.1 → 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 +85 -4
- package/dist/bin.js +1 -1
- package/dist/{chunk-CCOFMK5K.js → chunk-5GZMAASA.js} +810 -37
- package/dist/chunk-5GZMAASA.js.map +1 -0
- package/dist/index.d.ts +238 -10
- package/dist/index.js +9 -1
- package/package.json +13 -2
- package/dist/chunk-CCOFMK5K.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { KeyObject } from 'node:crypto';
|
|
1
2
|
import { Server } from 'node:http';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Who the agents are. The issuer holds no list of its own: the company's
|
|
5
|
-
* identity provider is the record (
|
|
6
|
+
* identity provider is the record (`keycloak.ts`, `auth0.ts`, `okta.ts`), read
|
|
6
7
|
* through this interface, and the issuer turns what it says into cards,
|
|
7
8
|
* keys in the policy, and grants. Pidgeon is the format and the check,
|
|
8
9
|
* never the identity provider.
|
|
@@ -42,10 +43,50 @@ declare function staticDirectory(agents: DirectoryAgent[]): Directory;
|
|
|
42
43
|
*/
|
|
43
44
|
declare function cachedDirectory(inner: Directory, seconds?: number, now?: () => number): Directory;
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* A person signs in at the issuer: Pidgeon Cloud's person flow, with the
|
|
48
|
+
* company's own identity provider where Cloud has its consent page.
|
|
49
|
+
*
|
|
50
|
+
* The site speaks to the issuer exactly as it speaks to Cloud (the
|
|
51
|
+
* authorization code flow with PKCE and a nonce, `@pidgeon-ai/sign-in`'s
|
|
52
|
+
* `login` and `callback`). The issuer is a relying party of the company's
|
|
53
|
+
* OpenID Connect provider (Keycloak, Auth0, Okta, Entra): it sends the
|
|
54
|
+
* browser there with its own PKCE, state and nonce, checks the ID token
|
|
55
|
+
* that comes back, and signs the person in to the site as `kind: person`
|
|
56
|
+
* with the provider's `sub` and a verified address at the domain.
|
|
57
|
+
*
|
|
58
|
+
* **No database.** What a store would hold travels sealed (AES-256-GCM
|
|
59
|
+
* under `PIDGEON_ISSUER_SECRET`): the sign-in in progress in an HttpOnly
|
|
60
|
+
* cookie on the issuer's host, bound to the browser that started it; the
|
|
61
|
+
* code, sixty seconds, used once through the issuer's replay store.
|
|
62
|
+
* Rotating the secret ends the sign-ins in flight, and nothing else.
|
|
63
|
+
*/
|
|
64
|
+
/** The company's identity provider, as its relying party. */
|
|
65
|
+
interface PersonOptions {
|
|
66
|
+
/** At least 32 characters. Seals the sign-in in progress and the code. */
|
|
67
|
+
secret: string;
|
|
68
|
+
oidc: {
|
|
69
|
+
/** The provider's issuer, exactly as its ID tokens say: `https://sso.acme.com/realms/acme`. */
|
|
70
|
+
issuer: string;
|
|
71
|
+
/**
|
|
72
|
+
* Where the issuer fetches the provider's configuration, when it reaches
|
|
73
|
+
* the provider by another name than browsers do. Default
|
|
74
|
+
* `<issuer>/.well-known/openid-configuration`.
|
|
75
|
+
*/
|
|
76
|
+
discoveryUrl?: string;
|
|
77
|
+
clientId: string;
|
|
78
|
+
clientSecret: string;
|
|
79
|
+
/** How the issuer authenticates at the provider's token endpoint. Default `client_secret_basic`. */
|
|
80
|
+
tokenAuth?: 'client_secret_basic' | 'client_secret_post';
|
|
81
|
+
};
|
|
82
|
+
/** Domains a person's verified address may be at. Default the issuer's domain. */
|
|
83
|
+
emailDomains?: string[];
|
|
84
|
+
}
|
|
85
|
+
|
|
45
86
|
/**
|
|
46
87
|
* The issuer's signing key, behind one interface so custody never touches
|
|
47
|
-
* the protocol: a file
|
|
48
|
-
* same three members and nothing else changes.
|
|
88
|
+
* the protocol: a file, AWS KMS (`kms.ts`), or an HSM over PKCS#11
|
|
89
|
+
* implementing the same three members, and nothing else changes.
|
|
49
90
|
*
|
|
50
91
|
* Everything the issuer signs is a JWS signing input (a card, an ID token,
|
|
51
92
|
* a grant), a few hundred bytes, so a KMS that signs pure Ed25519 only up to
|
|
@@ -88,7 +129,9 @@ declare function seedSigner(seed: string, options?: {
|
|
|
88
129
|
* work against it unchanged: the policy and the card at `post.<domain>`
|
|
89
130
|
* (the draft's §discovery and §card), the token exchange an agent signs
|
|
90
131
|
* (RFC 8693, Web Bot Auth's profile) and the ID token a site checks
|
|
91
|
-
* (`@pidgeon-ai/sign-in`), grants (§grants)
|
|
132
|
+
* (`@pidgeon-ai/sign-in`), grants (§grants), and a person's sign-in, the
|
|
133
|
+
* authorization code flow with PKCE, through the company's own identity
|
|
134
|
+
* provider (`person.ts`). The formats are the app's own
|
|
92
135
|
* (`src/lib/post/card.ts`, `grant.ts`, `pidgeon-sign-in.ts`), written out
|
|
93
136
|
* here because a package cannot import the app; `tests/unit/issuer.test.ts`
|
|
94
137
|
* holds them equal by reading what this signs with the app's own readers.
|
|
@@ -97,7 +140,7 @@ declare function seedSigner(seed: string, options?: {
|
|
|
97
140
|
* used once through `replay`, in memory unless a shared store is passed.
|
|
98
141
|
* Run one replica, or pass one.
|
|
99
142
|
*
|
|
100
|
-
* Left out on purpose:
|
|
143
|
+
* Left out on purpose: userinfo, introspection and
|
|
101
144
|
* revocation (each needs a store; an ID token lives five minutes and
|
|
102
145
|
* revoking an agent is disabling it in the identity provider), dynamic
|
|
103
146
|
* client registration, and the card log.
|
|
@@ -110,6 +153,9 @@ declare const PATHS: {
|
|
|
110
153
|
readonly card: "/.well-known/post/card";
|
|
111
154
|
readonly directory: "/.well-known/http-message-signatures-directory";
|
|
112
155
|
readonly token: "/api/post/oidc/token";
|
|
156
|
+
readonly authorize: "/api/post/oidc/authorize";
|
|
157
|
+
/** The issuer's own: where the company's identity provider sends a person back. Cloud has none. */
|
|
158
|
+
readonly callback: "/api/post/oidc/callback";
|
|
113
159
|
readonly jwks: "/api/post/oidc/jwks";
|
|
114
160
|
readonly grants: "/api/post/grants";
|
|
115
161
|
};
|
|
@@ -133,10 +179,14 @@ interface GrantRule {
|
|
|
133
179
|
/** How long each signed copy lasts. Default 30. */
|
|
134
180
|
days?: number;
|
|
135
181
|
}
|
|
136
|
-
/**
|
|
182
|
+
/**
|
|
183
|
+
* A site, registered by hand: its `client_id`, the host its grants must be
|
|
184
|
+
* for, and where a person's sign-in may return to, each matched exactly.
|
|
185
|
+
*/
|
|
137
186
|
interface StaticClient {
|
|
138
187
|
client_id: string;
|
|
139
188
|
host: string;
|
|
189
|
+
redirect_uris?: string[];
|
|
140
190
|
}
|
|
141
191
|
/** Remembers a signature's `keyid nonce` until it expires; false when it was used. */
|
|
142
192
|
interface ReplayStore {
|
|
@@ -162,6 +212,8 @@ interface IssuerOptions {
|
|
|
162
212
|
* make it fetch an arbitrary URL.
|
|
163
213
|
*/
|
|
164
214
|
clientMetadataHosts?: string[];
|
|
215
|
+
/** A person's sign-in, through the company's identity provider. Absent: agents only. */
|
|
216
|
+
person?: PersonOptions;
|
|
165
217
|
replay?: ReplayStore;
|
|
166
218
|
fetch?: typeof fetch;
|
|
167
219
|
/** Milliseconds since the epoch, for tests. */
|
|
@@ -241,6 +293,135 @@ interface KeycloakOptions {
|
|
|
241
293
|
}
|
|
242
294
|
declare function keycloakDirectory(options: KeycloakOptions): Directory;
|
|
243
295
|
|
|
296
|
+
/**
|
|
297
|
+
* Auth0 as the directory: the issuer reads the tenant's Management API and
|
|
298
|
+
* never writes it.
|
|
299
|
+
*
|
|
300
|
+
* **An agent is a machine-to-machine application** (`app_type:
|
|
301
|
+
* non_interactive`) whose `client_metadata` says so. Auth0 metadata keys
|
|
302
|
+
* cannot hold a dot, so the names are Keycloak's with an underscore:
|
|
303
|
+
*
|
|
304
|
+
* | `client_metadata` | Becomes |
|
|
305
|
+
* | ------------------ | ------------------------------------------------------------- |
|
|
306
|
+
* | `pidgeon_key` | the agent's Ed25519 public key (`x`, base64url); required |
|
|
307
|
+
* | `pidgeon_address` | its address, at the issuer's domain; required |
|
|
308
|
+
* | `pidgeon_kind` | `agent` (default) or `service` |
|
|
309
|
+
* | `pidgeon_groups` | comma-separated, what the config's `grants` map |
|
|
310
|
+
* | `pidgeon_disabled` | `true`: not an agent, from its next sign-in |
|
|
311
|
+
*
|
|
312
|
+
* **Disabling.** An Auth0 application has no enabled switch, so an agent
|
|
313
|
+
* is disabled with `pidgeon_disabled` or by deleting the application.
|
|
314
|
+
* Whoever holds `update:clients` can set or clear it, so it is exactly as
|
|
315
|
+
* strong as that permission, the same people who could change its key.
|
|
316
|
+
*
|
|
317
|
+
* **One key, two uses is not possible here.** Auth0's Private Key JWT takes
|
|
318
|
+
* RS256, RS384 and PS256 with RSA keys only, not Ed25519, so the agent
|
|
319
|
+
* authenticates to Auth0 some other way and names its Pidgeon key in
|
|
320
|
+
* `pidgeon_key`.
|
|
321
|
+
*
|
|
322
|
+
* The card's `sub` is the `client_id`, which Auth0 generates and never lets
|
|
323
|
+
* anyone change; its documentation does not say whether a deleted
|
|
324
|
+
* application's id can come back. `created_at` is the application's.
|
|
325
|
+
*
|
|
326
|
+
* **The issuer's own credential** is a machine-to-machine application
|
|
327
|
+
* authorized for the Management API with `read:clients` only: never
|
|
328
|
+
* `read:client_keys` or `read:client_credentials`, which expose secrets.
|
|
329
|
+
* Its secret comes from the environment.
|
|
330
|
+
*/
|
|
331
|
+
interface Auth0Options {
|
|
332
|
+
/** The tenant's domain: `acme.eu.auth0.com`, or its custom domain. */
|
|
333
|
+
tenant: string;
|
|
334
|
+
/** The issuer's own application. */
|
|
335
|
+
clientId: string;
|
|
336
|
+
clientSecret: string;
|
|
337
|
+
/** The domain agents' addresses are at. */
|
|
338
|
+
domain: string;
|
|
339
|
+
fetch?: typeof fetch;
|
|
340
|
+
/** Milliseconds since the epoch, for tests. */
|
|
341
|
+
now?: () => number;
|
|
342
|
+
}
|
|
343
|
+
declare function auth0Directory(options: Auth0Options): Directory;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Okta as the directory: the issuer reads the org's Apps API and never
|
|
347
|
+
* writes it.
|
|
348
|
+
*
|
|
349
|
+
* **An agent is an active OAuth 2.0 service app** (`application_type:
|
|
350
|
+
* service`, client credentials) whose `profile` names it. An Okta group
|
|
351
|
+
* holds people, never apps, so the agent's groups live in the profile too,
|
|
352
|
+
* as Okta's own `profile.groupallowlist` pattern does:
|
|
353
|
+
*
|
|
354
|
+
* ```json
|
|
355
|
+
* "profile": { "pidgeon": { "key": "<x>", "address": "support@acme.com", "kind": "agent", "groups": ["refunds"] } }
|
|
356
|
+
* ```
|
|
357
|
+
*
|
|
358
|
+
* A deactivated app (`status: INACTIVE`) or a deleted one is not an agent
|
|
359
|
+
* from its next sign-in. The card's `sub` is the app's id; `created_at` is
|
|
360
|
+
* the app's `created`.
|
|
361
|
+
*
|
|
362
|
+
* **One key, two uses is not possible here.** An Okta app's JWKS takes RSA
|
|
363
|
+
* and EC keys only, not Ed25519, so the agent authenticates to Okta with
|
|
364
|
+
* another key and names its Pidgeon key in the profile.
|
|
365
|
+
*
|
|
366
|
+
* **The issuer's own credential** is a service app of its own, granted the
|
|
367
|
+
* `okta.apps.read` scope and a read-only admin role (Okta requires both).
|
|
368
|
+
* Okta takes only Private Key JWT for its own scopes, so the issuer signs a
|
|
369
|
+
* client assertion with an RSA or P-256 key whose public half is in that
|
|
370
|
+
* app's JWKS; the private half comes from the environment.
|
|
371
|
+
*/
|
|
372
|
+
interface OktaOptions {
|
|
373
|
+
/** The org: `https://acme.okta.com`. */
|
|
374
|
+
org: string;
|
|
375
|
+
/** The issuer's own service app. */
|
|
376
|
+
clientId: string;
|
|
377
|
+
/** Its RSA or P-256 private key, PEM, for the client assertion. */
|
|
378
|
+
privateKey: string | KeyObject;
|
|
379
|
+
/** That key's `kid` in the app's JWKS, when the app has more than one. */
|
|
380
|
+
keyId?: string;
|
|
381
|
+
/** The domain agents' addresses are at. */
|
|
382
|
+
domain: string;
|
|
383
|
+
fetch?: typeof fetch;
|
|
384
|
+
/** Milliseconds since the epoch, for tests. */
|
|
385
|
+
now?: () => number;
|
|
386
|
+
}
|
|
387
|
+
declare function oktaDirectory(options: OktaOptions): Directory;
|
|
388
|
+
|
|
389
|
+
/** The two KMS calls the issuer makes, as `@aws-sdk/client-kms` shapes them. */
|
|
390
|
+
interface KmsApi {
|
|
391
|
+
getPublicKey(input: {
|
|
392
|
+
KeyId: string;
|
|
393
|
+
}): Promise<{
|
|
394
|
+
KeyId?: string;
|
|
395
|
+
KeySpec?: string;
|
|
396
|
+
KeyUsage?: string;
|
|
397
|
+
SigningAlgorithms?: string[];
|
|
398
|
+
PublicKey?: Uint8Array;
|
|
399
|
+
}>;
|
|
400
|
+
sign(input: {
|
|
401
|
+
KeyId: string;
|
|
402
|
+
Message: Uint8Array;
|
|
403
|
+
MessageType: 'RAW';
|
|
404
|
+
SigningAlgorithm: string;
|
|
405
|
+
}): Promise<{
|
|
406
|
+
KeyId?: string;
|
|
407
|
+
Signature?: Uint8Array;
|
|
408
|
+
}>;
|
|
409
|
+
}
|
|
410
|
+
interface KmsSignerOptions {
|
|
411
|
+
/** The key's ARN, id, or an alias (`alias/pidgeon-issuer`), resolved once at start. */
|
|
412
|
+
keyId: string;
|
|
413
|
+
/** Default the SDK's: `AWS_REGION`, then the profile's. */
|
|
414
|
+
region?: string;
|
|
415
|
+
kms?: KmsApi;
|
|
416
|
+
}
|
|
417
|
+
declare function kmsSigner(options: KmsSignerOptions): Promise<Signer & {
|
|
418
|
+
keyArn: string;
|
|
419
|
+
}>;
|
|
420
|
+
/** A key in KMS the issuer no longer signs with, published until `notAfter`: its public half only. */
|
|
421
|
+
declare function kmsRetiredKey(options: KmsSignerOptions & {
|
|
422
|
+
notAfter: Date;
|
|
423
|
+
}): Promise<RetiredKey>;
|
|
424
|
+
|
|
244
425
|
/**
|
|
245
426
|
* `issuer.json`, the one file a company writes (`issuer.example.json`).
|
|
246
427
|
* Secrets never go in it: the key is a file it names (mounted as a secret)
|
|
@@ -251,11 +432,15 @@ interface IssuerFile {
|
|
|
251
432
|
domain: string;
|
|
252
433
|
issuer?: string;
|
|
253
434
|
organisation?: string;
|
|
254
|
-
/**
|
|
255
|
-
|
|
435
|
+
/**
|
|
436
|
+
* The key file, relative to this file, or a key in AWS KMS (`{ "kms":
|
|
437
|
+
* "arn:aws:kms:…" }`, an `ECC_NIST_EDWARDS25519` key). `PIDGEON_ISSUER_KEY`
|
|
438
|
+
* (the seed) wins when set.
|
|
439
|
+
*/
|
|
440
|
+
key?: KeyRef;
|
|
256
441
|
/** Keys being withdrawn: published until `not_after`. */
|
|
257
442
|
retired?: {
|
|
258
|
-
key:
|
|
443
|
+
key: KeyRef;
|
|
259
444
|
not_after: string;
|
|
260
445
|
}[];
|
|
261
446
|
directory: {
|
|
@@ -271,6 +456,44 @@ interface IssuerFile {
|
|
|
271
456
|
/** The group whose members are agents. Default `agents`. */
|
|
272
457
|
group?: string;
|
|
273
458
|
};
|
|
459
|
+
} | {
|
|
460
|
+
auth0: {
|
|
461
|
+
/** The tenant's domain: `acme.eu.auth0.com`. */
|
|
462
|
+
tenant: string;
|
|
463
|
+
/** The issuer's own machine-to-machine application, with `read:clients` only. */
|
|
464
|
+
client_id: string;
|
|
465
|
+
/** The environment variable holding its secret. Default `AUTH0_CLIENT_SECRET`. */
|
|
466
|
+
client_secret_env?: string;
|
|
467
|
+
};
|
|
468
|
+
} | {
|
|
469
|
+
okta: {
|
|
470
|
+
/** The org: `https://acme.okta.com`. */
|
|
471
|
+
org: string;
|
|
472
|
+
/** The issuer's own service app, with `okta.apps.read` and a read-only admin role. */
|
|
473
|
+
client_id: string;
|
|
474
|
+
/** The environment variable holding its RSA or P-256 private key, PEM. Default `OKTA_PRIVATE_KEY`. */
|
|
475
|
+
private_key_env?: string;
|
|
476
|
+
/** That key's `kid` in the app's JWKS. */
|
|
477
|
+
key_id?: string;
|
|
478
|
+
};
|
|
479
|
+
};
|
|
480
|
+
/**
|
|
481
|
+
* A person's sign-in, through the company's OpenID Connect provider, with
|
|
482
|
+
* the issuer as one of its clients. Needs `PIDGEON_ISSUER_SECRET`.
|
|
483
|
+
*/
|
|
484
|
+
person?: {
|
|
485
|
+
oidc: {
|
|
486
|
+
/** The provider's issuer, as its ID tokens say. */
|
|
487
|
+
issuer: string;
|
|
488
|
+
/** Where the issuer reaches the provider's configuration, when not at its issuer URL. */
|
|
489
|
+
discovery_url?: string;
|
|
490
|
+
client_id: string;
|
|
491
|
+
/** The environment variable holding its secret. Default `PIDGEON_PERSON_CLIENT_SECRET`. */
|
|
492
|
+
client_secret_env?: string;
|
|
493
|
+
token_auth?: 'client_secret_basic' | 'client_secret_post';
|
|
494
|
+
};
|
|
495
|
+
/** Default the domain. */
|
|
496
|
+
email_domains?: string[];
|
|
274
497
|
};
|
|
275
498
|
grants?: GrantRule[];
|
|
276
499
|
clients?: StaticClient[];
|
|
@@ -278,6 +501,11 @@ interface IssuerFile {
|
|
|
278
501
|
/** How long the list of agents is held for the public reads, in seconds. Default 60. */
|
|
279
502
|
directory_cache_seconds?: number;
|
|
280
503
|
}
|
|
504
|
+
/** A key file's path, or a KMS key: its ARN, id or alias, and its region when not the default. */
|
|
505
|
+
type KeyRef = string | {
|
|
506
|
+
kms: string;
|
|
507
|
+
region?: string;
|
|
508
|
+
};
|
|
281
509
|
declare function loadConfig(path: string, env?: Record<string, string | undefined>): Promise<IssuerOptions>;
|
|
282
510
|
|
|
283
511
|
/**
|
|
@@ -304,4 +532,4 @@ declare function runIssuer(args: string[], env?: Record<string, string | undefin
|
|
|
304
532
|
log?: (line: string) => void;
|
|
305
533
|
}): Promise<string>;
|
|
306
534
|
|
|
307
|
-
export { type Directory, type DirectoryAgent, type GrantRule, type Issuer, type IssuerFile, type IssuerOptions, type KeycloakOptions, PATHS, type ReplayStore, type RetiredKey, type Signer, type StaticClient, TOKEN_EXCHANGE, UsageError, cachedDirectory, createIssuer, fileSigner, keycloakDirectory, loadConfig, memoryReplayStore, runIssuer, seedSigner, serve, staticDirectory };
|
|
535
|
+
export { type Auth0Options, type Directory, type DirectoryAgent, type GrantRule, type Issuer, type IssuerFile, type IssuerOptions, type KeyRef, type KeycloakOptions, type KmsApi, type KmsSignerOptions, type OktaOptions, PATHS, type PersonOptions, type ReplayStore, type RetiredKey, type Signer, type StaticClient, TOKEN_EXCHANGE, UsageError, auth0Directory, cachedDirectory, createIssuer, fileSigner, keycloakDirectory, kmsRetiredKey, kmsSigner, loadConfig, memoryReplayStore, oktaDirectory, runIssuer, seedSigner, serve, staticDirectory };
|
package/dist/index.js
CHANGED
|
@@ -3,27 +3,35 @@ import {
|
|
|
3
3
|
PATHS,
|
|
4
4
|
TOKEN_EXCHANGE,
|
|
5
5
|
UsageError,
|
|
6
|
+
auth0Directory,
|
|
6
7
|
cachedDirectory,
|
|
7
8
|
createIssuer,
|
|
8
9
|
fileSigner,
|
|
9
10
|
keycloakDirectory,
|
|
11
|
+
kmsRetiredKey,
|
|
12
|
+
kmsSigner,
|
|
10
13
|
loadConfig,
|
|
11
14
|
memoryReplayStore,
|
|
15
|
+
oktaDirectory,
|
|
12
16
|
runIssuer,
|
|
13
17
|
seedSigner,
|
|
14
18
|
serve,
|
|
15
19
|
staticDirectory
|
|
16
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-5GZMAASA.js";
|
|
17
21
|
export {
|
|
18
22
|
PATHS,
|
|
19
23
|
TOKEN_EXCHANGE,
|
|
20
24
|
UsageError,
|
|
25
|
+
auth0Directory,
|
|
21
26
|
cachedDirectory,
|
|
22
27
|
createIssuer,
|
|
23
28
|
fileSigner,
|
|
24
29
|
keycloakDirectory,
|
|
30
|
+
kmsRetiredKey,
|
|
31
|
+
kmsSigner,
|
|
25
32
|
loadConfig,
|
|
26
33
|
memoryReplayStore,
|
|
34
|
+
oktaDirectory,
|
|
27
35
|
runIssuer,
|
|
28
36
|
seedSigner,
|
|
29
37
|
serve,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pidgeon-ai/issuer",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A Post issuer you run yourself, inside your own network: your domain signs your AI agents' cards and sign-ins with a key that never leaves it, for the agents your identity provider (Keycloak) says you have.",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "A Post issuer you run yourself, inside your own network: your domain signs your AI agents' cards and sign-ins with a key that never leaves it, for the agents your identity provider (Keycloak, Auth0, Okta) says you have.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-identity",
|
|
7
7
|
"ai-agents",
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"openid-connect",
|
|
10
10
|
"token-exchange",
|
|
11
11
|
"keycloak",
|
|
12
|
+
"auth0",
|
|
13
|
+
"okta",
|
|
12
14
|
"web-bot-auth",
|
|
13
15
|
"pidgeon",
|
|
14
16
|
"post"
|
|
@@ -43,7 +45,16 @@
|
|
|
43
45
|
"publishConfig": {
|
|
44
46
|
"access": "public"
|
|
45
47
|
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@aws-sdk/client-kms": "^3.1164.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependenciesMeta": {
|
|
52
|
+
"@aws-sdk/client-kms": {
|
|
53
|
+
"optional": true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
46
56
|
"devDependencies": {
|
|
57
|
+
"@aws-sdk/client-kms": "^3.1164.0",
|
|
47
58
|
"tsup": "^8.5.0",
|
|
48
59
|
"typescript": "^5",
|
|
49
60
|
"@pidgeon-ai/id": "0.2.0"
|