@pidgeon-ai/issuer 0.1.1 → 0.2.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 +32 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-CCOFMK5K.js → chunk-BXZ2EI2Y.js} +482 -31
- package/dist/chunk-BXZ2EI2Y.js.map +1 -0
- package/dist/index.d.ts +73 -4
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CCOFMK5K.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,46 @@ declare function staticDirectory(agents: DirectoryAgent[]): Directory;
|
|
|
42
42
|
*/
|
|
43
43
|
declare function cachedDirectory(inner: Directory, seconds?: number, now?: () => number): Directory;
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* A person signs in at the issuer: Pidgeon Cloud's person flow, with the
|
|
47
|
+
* company's own identity provider where Cloud has its consent page.
|
|
48
|
+
*
|
|
49
|
+
* The site speaks to the issuer exactly as it speaks to Cloud (the
|
|
50
|
+
* authorization code flow with PKCE and a nonce, `@pidgeon-ai/sign-in`'s
|
|
51
|
+
* `login` and `callback`). The issuer is a relying party of the company's
|
|
52
|
+
* OpenID Connect provider (Keycloak, Auth0, Okta, Entra): it sends the
|
|
53
|
+
* browser there with its own PKCE, state and nonce, checks the ID token
|
|
54
|
+
* that comes back, and signs the person in to the site as `kind: person`
|
|
55
|
+
* with the provider's `sub` and a verified address at the domain.
|
|
56
|
+
*
|
|
57
|
+
* **No database.** What a store would hold travels sealed (AES-256-GCM
|
|
58
|
+
* under `PIDGEON_ISSUER_SECRET`): the sign-in in progress in an HttpOnly
|
|
59
|
+
* cookie on the issuer's host, bound to the browser that started it; the
|
|
60
|
+
* code, sixty seconds, used once through the issuer's replay store.
|
|
61
|
+
* Rotating the secret ends the sign-ins in flight, and nothing else.
|
|
62
|
+
*/
|
|
63
|
+
/** The company's identity provider, as its relying party. */
|
|
64
|
+
interface PersonOptions {
|
|
65
|
+
/** At least 32 characters. Seals the sign-in in progress and the code. */
|
|
66
|
+
secret: string;
|
|
67
|
+
oidc: {
|
|
68
|
+
/** The provider's issuer, exactly as its ID tokens say: `https://sso.acme.com/realms/acme`. */
|
|
69
|
+
issuer: string;
|
|
70
|
+
/**
|
|
71
|
+
* Where the issuer fetches the provider's configuration, when it reaches
|
|
72
|
+
* the provider by another name than browsers do. Default
|
|
73
|
+
* `<issuer>/.well-known/openid-configuration`.
|
|
74
|
+
*/
|
|
75
|
+
discoveryUrl?: string;
|
|
76
|
+
clientId: string;
|
|
77
|
+
clientSecret: string;
|
|
78
|
+
/** How the issuer authenticates at the provider's token endpoint. Default `client_secret_basic`. */
|
|
79
|
+
tokenAuth?: 'client_secret_basic' | 'client_secret_post';
|
|
80
|
+
};
|
|
81
|
+
/** Domains a person's verified address may be at. Default the issuer's domain. */
|
|
82
|
+
emailDomains?: string[];
|
|
83
|
+
}
|
|
84
|
+
|
|
45
85
|
/**
|
|
46
86
|
* The issuer's signing key, behind one interface so custody never touches
|
|
47
87
|
* the protocol: a file today; AWS KMS or an HSM over PKCS#11 implement the
|
|
@@ -88,7 +128,9 @@ declare function seedSigner(seed: string, options?: {
|
|
|
88
128
|
* work against it unchanged: the policy and the card at `post.<domain>`
|
|
89
129
|
* (the draft's §discovery and §card), the token exchange an agent signs
|
|
90
130
|
* (RFC 8693, Web Bot Auth's profile) and the ID token a site checks
|
|
91
|
-
* (`@pidgeon-ai/sign-in`), grants (§grants)
|
|
131
|
+
* (`@pidgeon-ai/sign-in`), grants (§grants), and a person's sign-in, the
|
|
132
|
+
* authorization code flow with PKCE, through the company's own identity
|
|
133
|
+
* provider (`person.ts`). The formats are the app's own
|
|
92
134
|
* (`src/lib/post/card.ts`, `grant.ts`, `pidgeon-sign-in.ts`), written out
|
|
93
135
|
* here because a package cannot import the app; `tests/unit/issuer.test.ts`
|
|
94
136
|
* holds them equal by reading what this signs with the app's own readers.
|
|
@@ -97,7 +139,7 @@ declare function seedSigner(seed: string, options?: {
|
|
|
97
139
|
* used once through `replay`, in memory unless a shared store is passed.
|
|
98
140
|
* Run one replica, or pass one.
|
|
99
141
|
*
|
|
100
|
-
* Left out on purpose:
|
|
142
|
+
* Left out on purpose: userinfo, introspection and
|
|
101
143
|
* revocation (each needs a store; an ID token lives five minutes and
|
|
102
144
|
* revoking an agent is disabling it in the identity provider), dynamic
|
|
103
145
|
* client registration, and the card log.
|
|
@@ -110,6 +152,9 @@ declare const PATHS: {
|
|
|
110
152
|
readonly card: "/.well-known/post/card";
|
|
111
153
|
readonly directory: "/.well-known/http-message-signatures-directory";
|
|
112
154
|
readonly token: "/api/post/oidc/token";
|
|
155
|
+
readonly authorize: "/api/post/oidc/authorize";
|
|
156
|
+
/** The issuer's own: where the company's identity provider sends a person back. Cloud has none. */
|
|
157
|
+
readonly callback: "/api/post/oidc/callback";
|
|
113
158
|
readonly jwks: "/api/post/oidc/jwks";
|
|
114
159
|
readonly grants: "/api/post/grants";
|
|
115
160
|
};
|
|
@@ -133,10 +178,14 @@ interface GrantRule {
|
|
|
133
178
|
/** How long each signed copy lasts. Default 30. */
|
|
134
179
|
days?: number;
|
|
135
180
|
}
|
|
136
|
-
/**
|
|
181
|
+
/**
|
|
182
|
+
* A site, registered by hand: its `client_id`, the host its grants must be
|
|
183
|
+
* for, and where a person's sign-in may return to, each matched exactly.
|
|
184
|
+
*/
|
|
137
185
|
interface StaticClient {
|
|
138
186
|
client_id: string;
|
|
139
187
|
host: string;
|
|
188
|
+
redirect_uris?: string[];
|
|
140
189
|
}
|
|
141
190
|
/** Remembers a signature's `keyid nonce` until it expires; false when it was used. */
|
|
142
191
|
interface ReplayStore {
|
|
@@ -162,6 +211,8 @@ interface IssuerOptions {
|
|
|
162
211
|
* make it fetch an arbitrary URL.
|
|
163
212
|
*/
|
|
164
213
|
clientMetadataHosts?: string[];
|
|
214
|
+
/** A person's sign-in, through the company's identity provider. Absent: agents only. */
|
|
215
|
+
person?: PersonOptions;
|
|
165
216
|
replay?: ReplayStore;
|
|
166
217
|
fetch?: typeof fetch;
|
|
167
218
|
/** Milliseconds since the epoch, for tests. */
|
|
@@ -272,6 +323,24 @@ interface IssuerFile {
|
|
|
272
323
|
group?: string;
|
|
273
324
|
};
|
|
274
325
|
};
|
|
326
|
+
/**
|
|
327
|
+
* A person's sign-in, through the company's OpenID Connect provider, with
|
|
328
|
+
* the issuer as one of its clients. Needs `PIDGEON_ISSUER_SECRET`.
|
|
329
|
+
*/
|
|
330
|
+
person?: {
|
|
331
|
+
oidc: {
|
|
332
|
+
/** The provider's issuer, as its ID tokens say. */
|
|
333
|
+
issuer: string;
|
|
334
|
+
/** Where the issuer reaches the provider's configuration, when not at its issuer URL. */
|
|
335
|
+
discovery_url?: string;
|
|
336
|
+
client_id: string;
|
|
337
|
+
/** The environment variable holding its secret. Default `PIDGEON_PERSON_CLIENT_SECRET`. */
|
|
338
|
+
client_secret_env?: string;
|
|
339
|
+
token_auth?: 'client_secret_basic' | 'client_secret_post';
|
|
340
|
+
};
|
|
341
|
+
/** Default the domain. */
|
|
342
|
+
email_domains?: string[];
|
|
343
|
+
};
|
|
275
344
|
grants?: GrantRule[];
|
|
276
345
|
clients?: StaticClient[];
|
|
277
346
|
client_metadata_hosts?: string[];
|
|
@@ -304,4 +373,4 @@ declare function runIssuer(args: string[], env?: Record<string, string | undefin
|
|
|
304
373
|
log?: (line: string) => void;
|
|
305
374
|
}): Promise<string>;
|
|
306
375
|
|
|
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 };
|
|
376
|
+
export { type Directory, type DirectoryAgent, type GrantRule, type Issuer, type IssuerFile, type IssuerOptions, type KeycloakOptions, PATHS, type PersonOptions, type ReplayStore, type RetiredKey, type Signer, type StaticClient, TOKEN_EXCHANGE, UsageError, cachedDirectory, createIssuer, fileSigner, keycloakDirectory, loadConfig, memoryReplayStore, runIssuer, seedSigner, serve, staticDirectory };
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pidgeon-ai/issuer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
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.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-identity",
|