@coffre/core 0.5.1 → 0.6.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.
- package/dist/{access-CwsFLfTz.d.ts → access-BpcBLDW9.d.ts} +16 -8
- package/dist/{access-pnJ-u4x2.js → access-DvwZzqRR.js} +17 -12
- package/dist/access.d.ts +2 -2
- package/dist/access.js +2 -2
- package/dist/identity.d.ts +146 -3
- package/dist/identity.js +386 -10
- package/dist/schemas.d.ts +3 -3
- package/dist/schemas.js +1 -1
- package/dist/vault.d.ts +56 -23
- package/dist/workloads.d.ts +23 -6
- package/dist/workloads.js +42 -10
- package/package.json +2 -2
- package/src/access-conversion.ts +1 -1
- package/src/access.ts +18 -12
- package/src/identity/github-app.ts +347 -0
- package/src/identity/index.ts +1 -0
- package/src/identity/signin/config.ts +66 -13
- package/src/identity/signin/github.ts +17 -5
- package/src/identity/workloads.ts +45 -8
- package/src/vault.ts +54 -18
|
@@ -166,7 +166,7 @@ declare function assignableToEnvironment(role: Role): boolean;
|
|
|
166
166
|
declare const INSTANCE_ROLES: {
|
|
167
167
|
readonly member: {
|
|
168
168
|
readonly name: "Member";
|
|
169
|
-
readonly description: "
|
|
169
|
+
readonly description: "None.";
|
|
170
170
|
readonly permissions: readonly [];
|
|
171
171
|
};
|
|
172
172
|
readonly auditor: {
|
|
@@ -186,7 +186,7 @@ declare const INSTANCE_ROLES: {
|
|
|
186
186
|
};
|
|
187
187
|
readonly owner: {
|
|
188
188
|
readonly name: "Owner";
|
|
189
|
-
readonly description: "Everything
|
|
189
|
+
readonly description: "Everything, every secret included.";
|
|
190
190
|
readonly permissions: readonly ["secret.read", "secret.write", "secret.archive", "audit.read", "environment.manage", "grant.manage", "project.manage"];
|
|
191
191
|
};
|
|
192
192
|
};
|
|
@@ -196,6 +196,16 @@ declare function isInstanceRole(value: string): value is InstanceRole;
|
|
|
196
196
|
declare function instanceRoleGrants(role: InstanceRole, permission: Permission): boolean;
|
|
197
197
|
/** The roles that manage people and access: Admin, and Owner, which adds every secret. */
|
|
198
198
|
declare function administers(role: InstanceRole): boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Whether a role and its scope make someone an Owner of the whole
|
|
201
|
+
* instance: the one standing the instance always keeps at least one of,
|
|
202
|
+
* and the one its bootstrap gives while it has none. An Owner scoped to
|
|
203
|
+
* `market` owns market, not the instance.
|
|
204
|
+
*/
|
|
205
|
+
declare function ownsInstance(standing: {
|
|
206
|
+
role: InstanceRole;
|
|
207
|
+
scope: Scope;
|
|
208
|
+
}): boolean;
|
|
199
209
|
/**
|
|
200
210
|
* Which projects, or environments, a scope takes in: all of them, only
|
|
201
211
|
* those listed, or all but those listed. Projects are listed by id, so a
|
|
@@ -303,8 +313,6 @@ declare function isCredentialScope(value: unknown): value is CredentialScope;
|
|
|
303
313
|
* cannot drift apart.
|
|
304
314
|
*/
|
|
305
315
|
type Holdings = {
|
|
306
|
-
/** Named in the vault's configuration: everything, everywhere. */
|
|
307
|
-
isRootAdmin: boolean;
|
|
308
316
|
/** `member` for service accounts, and for anyone not active. */
|
|
309
317
|
role: InstanceRole;
|
|
310
318
|
scope: Scope;
|
|
@@ -342,8 +350,8 @@ declare function allows(holder: Holdings, permission: Permission, place: Place):
|
|
|
342
350
|
*/
|
|
343
351
|
declare function mayManageAccess(actor: Holdings, place: Place): boolean;
|
|
344
352
|
/**
|
|
345
|
-
* Whether the holder runs the instance:
|
|
346
|
-
*
|
|
353
|
+
* Whether the holder runs the instance: an Admin or Owner whose scope
|
|
354
|
+
* narrows nothing. They add and remove people, set instance
|
|
347
355
|
* roles, and change the instance's settings; they read its whole log too
|
|
348
356
|
* (`readsWholeLog`). A scoped Admin manages only inside its scope, so it
|
|
349
357
|
* does none of these.
|
|
@@ -404,7 +412,7 @@ declare function issuesCredential(holder: Holdings, setting: ServiceSetting | nu
|
|
|
404
412
|
* Whether the holder reads the whole log, the instance's own entries
|
|
405
413
|
* (sign-ins, people, service accounts, settings) with every project's, and
|
|
406
414
|
* verifies it: whoever holds `audit.read` by an instance role whose scope
|
|
407
|
-
* narrows nothing, an Auditor's included
|
|
415
|
+
* narrows nothing, an Auditor's included. Reading, not
|
|
408
416
|
* running: an Auditor of the whole instance changes nothing it reads about.
|
|
409
417
|
* Anyone else reads the places they hold `audit.read` in.
|
|
410
418
|
*/
|
|
@@ -417,4 +425,4 @@ declare function readsWholeLog(holder: Holdings): boolean;
|
|
|
417
425
|
*/
|
|
418
426
|
declare function makesProjects(holder: Holdings): boolean;
|
|
419
427
|
//#endregion
|
|
420
|
-
export { instanceRoleGrants as A,
|
|
428
|
+
export { instanceRoleGrants as A, ownsInstance as B, allows as C, givesService as D, credentialScopeInWords as E, issuesCredential as F, setsUpServices as G, roleGrants as H, makesProjects as I, ConversionInput as J, unscoped as K, managesService as L, isInstanceRole as M, isRole as N, grantKind as O, isScope as P, convertEveryProjectGrants as Q, mayManageAccess as R, admits as S, covers as T, runsInstance as U, readsWholeLog as V, scopeInWords as W, EveryProjectGrant as X, ConvertedGrant as Y, Narrowed as Z, Role as _, Holdings as a, ServiceSetting as b, InstanceRole as c, PERMISSIONS as d, PROJECT_ONLY_PERMISSIONS as f, ROLE_NAMES as g, ROLES as h, GrantPlace as i, isCredentialScope as j, inScope as k, MAX_SCOPE_PLACES as l, Place as m, EVERYWHERE as n, INSTANCE_ROLES as o, Permission as p, Conversion as q, Filter as r, INSTANCE_ROLE_NAMES as s, CredentialScope as t, NOTHING as u, Scope as v, assignableToEnvironment as w, administers as x, ServiceAccount as y, normalScope as z };
|
|
@@ -137,7 +137,6 @@ function byRole(role, scope, grant) {
|
|
|
137
137
|
function holdsAlready(role, scope, held, grant, at) {
|
|
138
138
|
const lasting = held.filter((other) => outlasts(other.expiresAt, grant.expiresAt));
|
|
139
139
|
return ROLES[grant.role].permissions.every((permission) => allows({
|
|
140
|
-
isRootAdmin: false,
|
|
141
140
|
role,
|
|
142
141
|
scope,
|
|
143
142
|
grants: lasting
|
|
@@ -241,7 +240,7 @@ function assignableToEnvironment(role) {
|
|
|
241
240
|
const INSTANCE_ROLES = {
|
|
242
241
|
member: {
|
|
243
242
|
name: "Member",
|
|
244
|
-
description: "
|
|
243
|
+
description: "None.",
|
|
245
244
|
permissions: []
|
|
246
245
|
},
|
|
247
246
|
auditor: {
|
|
@@ -266,7 +265,7 @@ const INSTANCE_ROLES = {
|
|
|
266
265
|
},
|
|
267
266
|
owner: {
|
|
268
267
|
name: "Owner",
|
|
269
|
-
description: "Everything
|
|
268
|
+
description: "Everything, every secret included.",
|
|
270
269
|
permissions: [...PERMISSIONS]
|
|
271
270
|
}
|
|
272
271
|
};
|
|
@@ -281,6 +280,15 @@ function instanceRoleGrants(role, permission) {
|
|
|
281
280
|
function administers(role) {
|
|
282
281
|
return role === "admin" || role === "owner";
|
|
283
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Whether a role and its scope make someone an Owner of the whole
|
|
285
|
+
* instance: the one standing the instance always keeps at least one of,
|
|
286
|
+
* and the one its bootstrap gives while it has none. An Owner scoped to
|
|
287
|
+
* `market` owns market, not the instance.
|
|
288
|
+
*/
|
|
289
|
+
function ownsInstance(standing) {
|
|
290
|
+
return standing.role === "owner" && unscoped(standing.scope);
|
|
291
|
+
}
|
|
284
292
|
/** Every project and every environment. */
|
|
285
293
|
const EVERYWHERE = {
|
|
286
294
|
projects: "all",
|
|
@@ -387,7 +395,6 @@ function isCredentialScope(value) {
|
|
|
387
395
|
}
|
|
388
396
|
/** Someone who holds nothing: a stranger, a removed member, a tampered row. */
|
|
389
397
|
const NOTHING = {
|
|
390
|
-
isRootAdmin: false,
|
|
391
398
|
role: "member",
|
|
392
399
|
scope: EVERYWHERE,
|
|
393
400
|
grants: []
|
|
@@ -416,7 +423,6 @@ function covers(grant, place) {
|
|
|
416
423
|
*/
|
|
417
424
|
function allows(holder, permission, place) {
|
|
418
425
|
if (holder.credentialScope != null && !holdsAt(holder.credentialScope, permission, place)) return false;
|
|
419
|
-
if (holder.isRootAdmin) return true;
|
|
420
426
|
if (instanceRoleGrants(holder.role, permission) && inScope(holder.scope, place)) return true;
|
|
421
427
|
return holdsAt(holder.grants, permission, place);
|
|
422
428
|
}
|
|
@@ -434,14 +440,14 @@ function mayManageAccess(actor, place) {
|
|
|
434
440
|
return allows(actor, "grant.manage", place);
|
|
435
441
|
}
|
|
436
442
|
/**
|
|
437
|
-
* Whether the holder runs the instance:
|
|
438
|
-
*
|
|
443
|
+
* Whether the holder runs the instance: an Admin or Owner whose scope
|
|
444
|
+
* narrows nothing. They add and remove people, set instance
|
|
439
445
|
* roles, and change the instance's settings; they read its whole log too
|
|
440
446
|
* (`readsWholeLog`). A scoped Admin manages only inside its scope, so it
|
|
441
447
|
* does none of these.
|
|
442
448
|
*/
|
|
443
449
|
function runsInstance(holder) {
|
|
444
|
-
return
|
|
450
|
+
return administers(holder.role) && unscoped(holder.scope);
|
|
445
451
|
}
|
|
446
452
|
/**
|
|
447
453
|
* Whether `holder` may give a service account `role` at `place`: where
|
|
@@ -500,12 +506,12 @@ function issuesCredential(holder, setting, actor, account, scope) {
|
|
|
500
506
|
* Whether the holder reads the whole log, the instance's own entries
|
|
501
507
|
* (sign-ins, people, service accounts, settings) with every project's, and
|
|
502
508
|
* verifies it: whoever holds `audit.read` by an instance role whose scope
|
|
503
|
-
* narrows nothing, an Auditor's included
|
|
509
|
+
* narrows nothing, an Auditor's included. Reading, not
|
|
504
510
|
* running: an Auditor of the whole instance changes nothing it reads about.
|
|
505
511
|
* Anyone else reads the places they hold `audit.read` in.
|
|
506
512
|
*/
|
|
507
513
|
function readsWholeLog(holder) {
|
|
508
|
-
return
|
|
514
|
+
return instanceRoleGrants(holder.role, "audit.read") && unscoped(holder.scope);
|
|
509
515
|
}
|
|
510
516
|
/**
|
|
511
517
|
* Whether the holder may make a project: an Admin or Owner whose scope
|
|
@@ -514,9 +520,8 @@ function readsWholeLog(holder) {
|
|
|
514
520
|
* hold the project around them.
|
|
515
521
|
*/
|
|
516
522
|
function makesProjects(holder) {
|
|
517
|
-
if (holder.isRootAdmin) return true;
|
|
518
523
|
const { projects, environments } = holder.scope;
|
|
519
524
|
return administers(holder.role) && environments === "all" && (projects === "all" || "except" in projects);
|
|
520
525
|
}
|
|
521
526
|
//#endregion
|
|
522
|
-
export {
|
|
527
|
+
export { readsWholeLog as A, isScope as C, mayManageAccess as D, managesService as E, unscoped as F, convertEveryProjectGrants as I, runsInstance as M, scopeInWords as N, normalScope as O, setsUpServices as P, isRole as S, makesProjects as T, grantKind as _, NOTHING as a, isCredentialScope as b, ROLES as c, admits as d, allows as f, givesService as g, credentialScopeInWords as h, MAX_SCOPE_PLACES as i, roleGrants as j, ownsInstance as k, ROLE_NAMES as l, covers as m, INSTANCE_ROLES as n, PERMISSIONS as o, assignableToEnvironment as p, INSTANCE_ROLE_NAMES as r, PROJECT_ONLY_PERMISSIONS as s, EVERYWHERE as t, administers as u, inScope as v, issuesCredential as w, isInstanceRole as x, instanceRoleGrants as y };
|
package/dist/access.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as instanceRoleGrants, B as
|
|
2
|
-
export { type Conversion, type ConversionInput, type ConvertedGrant, CredentialScope, EVERYWHERE, type EveryProjectGrant, Filter, GrantPlace, Holdings, INSTANCE_ROLES, INSTANCE_ROLE_NAMES, InstanceRole, MAX_SCOPE_PLACES, NOTHING, type Narrowed, PERMISSIONS, PROJECT_ONLY_PERMISSIONS, Permission, Place, ROLES, ROLE_NAMES, Role, Scope, ServiceAccount, ServiceSetting, administers, admits, allows, assignableToEnvironment, convertEveryProjectGrants, covers, credentialScopeInWords, givesService, grantKind, inScope, instanceRoleGrants, isCredentialScope, isInstanceRole, isRole, isScope, issuesCredential, makesProjects, managesService, mayManageAccess, normalScope, readsWholeLog, roleGrants, runsInstance, scopeInWords, setsUpServices, unscoped };
|
|
1
|
+
import { A as instanceRoleGrants, B as ownsInstance, C as allows, D as givesService, E as credentialScopeInWords, F as issuesCredential, G as setsUpServices, H as roleGrants, I as makesProjects, J as ConversionInput, K as unscoped, L as managesService, M as isInstanceRole, N as isRole, O as grantKind, P as isScope, Q as convertEveryProjectGrants, R as mayManageAccess, S as admits, T as covers, U as runsInstance, V as readsWholeLog, W as scopeInWords, X as EveryProjectGrant, Y as ConvertedGrant, Z as Narrowed, _ as Role, a as Holdings, b as ServiceSetting, c as InstanceRole, d as PERMISSIONS, f as PROJECT_ONLY_PERMISSIONS, g as ROLE_NAMES, h as ROLES, i as GrantPlace, j as isCredentialScope, k as inScope, l as MAX_SCOPE_PLACES, m as Place, n as EVERYWHERE, o as INSTANCE_ROLES, p as Permission, q as Conversion, r as Filter, s as INSTANCE_ROLE_NAMES, t as CredentialScope, u as NOTHING, v as Scope, w as assignableToEnvironment, x as administers, y as ServiceAccount, z as normalScope } from "./access-BpcBLDW9.js";
|
|
2
|
+
export { type Conversion, type ConversionInput, type ConvertedGrant, CredentialScope, EVERYWHERE, type EveryProjectGrant, Filter, GrantPlace, Holdings, INSTANCE_ROLES, INSTANCE_ROLE_NAMES, InstanceRole, MAX_SCOPE_PLACES, NOTHING, type Narrowed, PERMISSIONS, PROJECT_ONLY_PERMISSIONS, Permission, Place, ROLES, ROLE_NAMES, Role, Scope, ServiceAccount, ServiceSetting, administers, admits, allows, assignableToEnvironment, convertEveryProjectGrants, covers, credentialScopeInWords, givesService, grantKind, inScope, instanceRoleGrants, isCredentialScope, isInstanceRole, isRole, isScope, issuesCredential, makesProjects, managesService, mayManageAccess, normalScope, ownsInstance, readsWholeLog, roleGrants, runsInstance, scopeInWords, setsUpServices, unscoped };
|
package/dist/access.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { EVERYWHERE, INSTANCE_ROLES, INSTANCE_ROLE_NAMES, MAX_SCOPE_PLACES, NOTHING, PERMISSIONS, PROJECT_ONLY_PERMISSIONS, ROLES, ROLE_NAMES, administers, admits, allows, assignableToEnvironment, convertEveryProjectGrants, covers, credentialScopeInWords, givesService, grantKind, inScope, instanceRoleGrants, isCredentialScope, isInstanceRole, isRole, isScope, issuesCredential, makesProjects, managesService, mayManageAccess, normalScope, readsWholeLog, roleGrants, runsInstance, scopeInWords, setsUpServices, unscoped };
|
|
1
|
+
import { A as readsWholeLog, C as isScope, D as mayManageAccess, E as managesService, F as unscoped, I as convertEveryProjectGrants, M as runsInstance, N as scopeInWords, O as normalScope, P as setsUpServices, S as isRole, T as makesProjects, _ as grantKind, a as NOTHING, b as isCredentialScope, c as ROLES, d as admits, f as allows, g as givesService, h as credentialScopeInWords, i as MAX_SCOPE_PLACES, j as roleGrants, k as ownsInstance, l as ROLE_NAMES, m as covers, n as INSTANCE_ROLES, o as PERMISSIONS, p as assignableToEnvironment, r as INSTANCE_ROLE_NAMES, s as PROJECT_ONLY_PERMISSIONS, t as EVERYWHERE, u as administers, v as inScope, w as issuesCredential, x as isInstanceRole, y as instanceRoleGrants } from "./access-DvwZzqRR.js";
|
|
2
|
+
export { EVERYWHERE, INSTANCE_ROLES, INSTANCE_ROLE_NAMES, MAX_SCOPE_PLACES, NOTHING, PERMISSIONS, PROJECT_ONLY_PERMISSIONS, ROLES, ROLE_NAMES, administers, admits, allows, assignableToEnvironment, convertEveryProjectGrants, covers, credentialScopeInWords, givesService, grantKind, inScope, instanceRoleGrants, isCredentialScope, isInstanceRole, isRole, isScope, issuesCredential, makesProjects, managesService, mayManageAccess, normalScope, ownsInstance, readsWholeLog, roleGrants, runsInstance, scopeInWords, setsUpServices, unscoped };
|
package/dist/identity.d.ts
CHANGED
|
@@ -1,5 +1,120 @@
|
|
|
1
1
|
import { BindingClaims, BindingInvalid, BindingPolicy, ClaimValue, EVENT_EXPOSURE, GITHUB_EVENTS, GITHUB_ISSUER, GITLAB_ISSUER, GITLAB_PIPELINE_SOURCES, MAX_BINDINGS, MAX_CLAIMS, MAX_CLAIM_BYTES, REQUIRED_CLAIMS, Starts, WORKLOAD_PROFILES, WorkloadProfile, canonicalClaims, checkBinding, checkFetchUrl, claimValues, defaultIssuer, differingClaims, fullRef, githubEventsAt, githubReusable, githubWorkflow, gitlabProject, workflowRef } from "./workloads.js";
|
|
2
2
|
import { JSONWebKeySet, JWTPayload } from "jose";
|
|
3
|
+
//#region src/identity/github-app.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The deployment's own GitHub App, made once with `githubApp(…)` and passed
|
|
6
|
+
* to each side that uses it (docs/github-app.md):
|
|
7
|
+
*
|
|
8
|
+
* const app = githubApp({ appId, privateKey, clientId, clientSecret });
|
|
9
|
+
* signin({ providers: [github({ app })], workloads: { limits, github: app } })
|
|
10
|
+
*
|
|
11
|
+
* Sign-in uses its OAuth client, `clientId` and `clientSecret`, as it would
|
|
12
|
+
* an OAuth app's (`github({ app })`). The forge side, `workloads.github`,
|
|
13
|
+
* uses its ID and private key: it lists the repositories the app is
|
|
14
|
+
* installed on, private ones too, where an owner trusts a workflow, and
|
|
15
|
+
* resolves `owner/name` to the IDs a binding names, with Metadata:
|
|
16
|
+
* read-only, so what it reaches there is the names and IDs of those
|
|
17
|
+
* repositories. Either side may go without the other: `github({ clientId,
|
|
18
|
+
* clientSecret })` signs in alone, and an app with no client lists alone.
|
|
19
|
+
*
|
|
20
|
+
* The app's private key lives with the app, the rest of the deployment's
|
|
21
|
+
* configuration, not in the vault: it opens no secret, and the vault's
|
|
22
|
+
* isolation is for the keys that do. It and the client secret stay in this
|
|
23
|
+
* object's private fields, and no message, log line or answer carries them,
|
|
24
|
+
* the JWTs it signs or the installation tokens they buy.
|
|
25
|
+
*
|
|
26
|
+
* The object lives as long as its configuration: the isolate's, on Workers,
|
|
27
|
+
* or the process's. It keeps settled values only (AGENTS.md, "What an
|
|
28
|
+
* isolate keeps"): the imported key, the app's name, and each
|
|
29
|
+
* installation's token until shortly before it expires. Concurrent first
|
|
30
|
+
* calls each import and ask for their own.
|
|
31
|
+
*/
|
|
32
|
+
export type GitHubAppOptions = {
|
|
33
|
+
/** The app's ID, on its settings page ("App ID"): a number, not its client ID. */
|
|
34
|
+
appId: string | number;
|
|
35
|
+
/** A private key generated on its settings page: the PEM file, as downloaded. */
|
|
36
|
+
privateKey: string;
|
|
37
|
+
/** Its OAuth client, on the same page: for signing people in with it, `github({ app })`. Both, or neither. */
|
|
38
|
+
clientId?: string;
|
|
39
|
+
clientSecret?: string;
|
|
40
|
+
/** https://github.com, or a GitHub Enterprise Server host: where people sign in. */
|
|
41
|
+
webUrl?: string;
|
|
42
|
+
/**
|
|
43
|
+
* https://api.github.com, or `${host}/api/v3` on Enterprise Server. The
|
|
44
|
+
* forge side takes github.com's only, or the dev IdP's on loopback: an
|
|
45
|
+
* Enterprise Server's runs sign their tokens under another issuer than
|
|
46
|
+
* the one its lookups bind to.
|
|
47
|
+
*/
|
|
48
|
+
apiUrl?: string;
|
|
49
|
+
};
|
|
50
|
+
/** A repository, by the IDs a binding names: what `GET /workloads/lookup` answers. */
|
|
51
|
+
export type GitHubRepository = {
|
|
52
|
+
github: string;
|
|
53
|
+
repositoryId: string;
|
|
54
|
+
ownerId: string;
|
|
55
|
+
private: boolean;
|
|
56
|
+
};
|
|
57
|
+
/** What the app reaches: its name and where to install it, the accounts it is installed on, and their repositories. */
|
|
58
|
+
export type GitHubAppRepositories = {
|
|
59
|
+
app: {
|
|
60
|
+
name: string;
|
|
61
|
+
installUrl: string;
|
|
62
|
+
};
|
|
63
|
+
/** The accounts it is installed on, by login. */
|
|
64
|
+
installations: string[];
|
|
65
|
+
/** By name. */
|
|
66
|
+
repositories: GitHubRepository[];
|
|
67
|
+
/** More than one listing reaches: the others are typed by name. */
|
|
68
|
+
truncated: boolean;
|
|
69
|
+
};
|
|
70
|
+
/** GitHub could not be asked, or refused the app: the message says which, for a person, and carries no credential. */
|
|
71
|
+
export declare class GitHubAppUnavailable extends Error {
|
|
72
|
+
constructor(message: string, options?: {
|
|
73
|
+
cause?: unknown;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/** Requests one listing makes at most, tokens included: well under a Worker's subrequest limit. */
|
|
77
|
+
export declare const MAX_LISTING_REQUESTS = 40;
|
|
78
|
+
/** A token GitHub issues for an hour is used until this long before it ends, so that none expires mid-call. */
|
|
79
|
+
export declare const TOKEN_MARGIN_MS: number;
|
|
80
|
+
export declare class GitHubApp {
|
|
81
|
+
#private;
|
|
82
|
+
readonly appId: string;
|
|
83
|
+
readonly webUrl: string;
|
|
84
|
+
readonly apiUrl: string;
|
|
85
|
+
/** Its OAuth client's ID, which is no secret; null when it was given none. */
|
|
86
|
+
readonly clientId: string | null;
|
|
87
|
+
constructor(options: {
|
|
88
|
+
appId: string;
|
|
89
|
+
apiUrl: string;
|
|
90
|
+
webUrl?: string;
|
|
91
|
+
pkcs8: Uint8Array<ArrayBuffer>;
|
|
92
|
+
client?: {
|
|
93
|
+
clientId: string;
|
|
94
|
+
clientSecret: string;
|
|
95
|
+
};
|
|
96
|
+
}, io?: {
|
|
97
|
+
fetch?: typeof fetch;
|
|
98
|
+
now?: () => number;
|
|
99
|
+
});
|
|
100
|
+
/** Its OAuth client, for `github({ app })`; null when it was given none. */
|
|
101
|
+
signinClient(): {
|
|
102
|
+
clientId: string;
|
|
103
|
+
clientSecret: string;
|
|
104
|
+
} | null;
|
|
105
|
+
/** Every repository of every account the app is installed on, as many as `MAX_LISTING_REQUESTS` reach. */
|
|
106
|
+
repositories(): Promise<GitHubAppRepositories>;
|
|
107
|
+
/** `owner/name`'s IDs, when the app is installed on it; null when it is not, its installation is suspended, or GitHub knows no such repository. */
|
|
108
|
+
repository(fullName: string): Promise<GitHubRepository | null>;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A private key's PEM as PKCS #8, which Web Crypto imports: GitHub's
|
|
112
|
+
* download is PKCS #1 (`BEGIN RSA PRIVATE KEY`), wrapped here as an RSA
|
|
113
|
+
* key's PKCS #8. Escaped newlines, as an environment variable sometimes
|
|
114
|
+
* holds them, are newlines. Never says what the key was.
|
|
115
|
+
*/
|
|
116
|
+
export declare function pkcs8Of(pem: string): Uint8Array<ArrayBuffer>;
|
|
117
|
+
//#endregion
|
|
3
118
|
//#region src/identity/signin/types.d.ts
|
|
4
119
|
/**
|
|
5
120
|
* What a provider reports about the person who just signed in.
|
|
@@ -216,6 +331,15 @@ export type WorkloadsOptions = {
|
|
|
216
331
|
* loopback too, so no instance anyone else can reach ever trusts one.
|
|
217
332
|
*/
|
|
218
333
|
allowLoopbackIssuersForDevelopment?: boolean;
|
|
334
|
+
/**
|
|
335
|
+
* The deployment's own GitHub App, `githubApp(…)`, installed on its
|
|
336
|
+
* organizations: where an owner trusts a workflow, the pages list the
|
|
337
|
+
* repositories it is installed on, private ones too, and a repository
|
|
338
|
+
* typed by name resolves through it (docs/github-app.md). The same value
|
|
339
|
+
* may sign people in, `github({ app })`. Left out, repositories are typed,
|
|
340
|
+
* and only public ones' IDs are looked up.
|
|
341
|
+
*/
|
|
342
|
+
github?: GitHubApp;
|
|
219
343
|
};
|
|
220
344
|
/** Cloudflare's rate-limiting binding, as coffre calls it; `processLimits()` has the same shape. */
|
|
221
345
|
export type RateLimiter = {
|
|
@@ -232,6 +356,7 @@ export type WorkloadLimits = {
|
|
|
232
356
|
export type WorkloadsConfig = {
|
|
233
357
|
allowLoopback: boolean;
|
|
234
358
|
limits: WorkloadLimits;
|
|
359
|
+
github: GitHubApp | null;
|
|
235
360
|
};
|
|
236
361
|
/**
|
|
237
362
|
* MCP clients, Claude among them, acting as the people who connect them,
|
|
@@ -303,14 +428,32 @@ export declare function microsoft(options: Credentials & {
|
|
|
303
428
|
label?: string;
|
|
304
429
|
tenant: string;
|
|
305
430
|
}): OidcSigninProvider;
|
|
306
|
-
/**
|
|
307
|
-
|
|
431
|
+
/**
|
|
432
|
+
* GitHub accounts; with `organization`, only that organization's members.
|
|
433
|
+
* Through an OAuth app, or a GitHub App's OAuth client, by its credentials;
|
|
434
|
+
* or the deployment's GitHub App, `github({ app })`, the same value its
|
|
435
|
+
* `workloads.github` lists repositories with:
|
|
436
|
+
*
|
|
437
|
+
* const app = githubApp({ appId, privateKey, clientId, clientSecret });
|
|
438
|
+
* signin({ providers: [github({ app, organization: 'acme' })], workloads: { limits, github: app } })
|
|
439
|
+
*/
|
|
440
|
+
export declare function github(options: {
|
|
308
441
|
id?: string;
|
|
309
442
|
label?: string;
|
|
310
443
|
organization?: string;
|
|
444
|
+
} & ((Credentials & {
|
|
311
445
|
webUrl?: string;
|
|
312
446
|
apiUrl?: string;
|
|
313
|
-
})
|
|
447
|
+
}) | {
|
|
448
|
+
app: GitHubApp;
|
|
449
|
+
})): GitHubSigninProvider;
|
|
450
|
+
/**
|
|
451
|
+
* The deployment's GitHub App, checked where it is written: its numeric ID
|
|
452
|
+
* and private key, and its OAuth client when it signs people in too. One
|
|
453
|
+
* value, passed to each side that uses it: `github({ app })` and
|
|
454
|
+
* `workloads.github` (`../github-app.ts`).
|
|
455
|
+
*/
|
|
456
|
+
export declare function githubApp(options: GitHubAppOptions): GitHubApp;
|
|
314
457
|
export declare function publicOrigin(value: string): string;
|
|
315
458
|
/** Sign-in configuration, checked: at least one provider, each whole, ids unique, lifetimes sane. */
|
|
316
459
|
export declare function defineSignin(options: {
|