@kici-dev/orchestrator 0.5.0 → 0.6.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/dist/__test-helpers__/fake-scaler-state-store.d.ts +24 -0
- package/dist/__test-helpers__/mock-db-query.d.ts +130 -0
- package/dist/__test-helpers__/mock-db.d.ts +23 -0
- package/dist/agent/dispatcher.d.ts +81 -13
- package/dist/agent/host-roster.d.ts +37 -5
- package/dist/agent/registry.d.ts +2 -0
- package/dist/app.d.ts +33 -6
- package/dist/approvals/apply-decision.d.ts +67 -19
- package/dist/approvals/held-run-release-wiring.d.ts +45 -0
- package/dist/approvals/independent-wiring.d.ts +55 -0
- package/dist/approvals/resume-router.d.ts +9 -0
- package/dist/approvals/triggerer-subject.d.ts +37 -0
- package/dist/cache/dep-cache.d.ts +54 -10
- package/dist/cache/global-eval-round-cache.d.ts +7 -0
- package/dist/cli/api-client.d.ts +18 -0
- package/dist/cli/commands/cluster-settings.d.ts +11 -0
- package/dist/cli/commands/diagnose.d.ts +6 -0
- package/dist/cli/commands/held-run.d.ts +58 -0
- package/dist/cli/commands/trust-policy.d.ts +117 -12
- package/dist/cli/kici-admin.d.ts +10 -0
- package/dist/cli.js +2272 -1025
- package/dist/cluster/cluster-identity.d.ts +3 -3
- package/dist/cluster/cluster-settings-reader.d.ts +7 -1
- package/dist/cluster/coordinator.d.ts +44 -0
- package/dist/cluster/index.d.ts +4 -0
- package/dist/cluster/peer-handler.d.ts +19 -0
- package/dist/cluster/peer-registry.d.ts +17 -0
- package/dist/cluster/plan-headroom-store.d.ts +26 -0
- package/dist/cluster/worker-eviction.d.ts +69 -0
- package/dist/cold-store/load-event-log-range.d.ts +10 -3
- package/dist/cold-store/load-secret-audit-log-range.d.ts +4 -3
- package/dist/cold-store/tables/secret-audit-log.d.ts +4 -3
- package/dist/config.d.ts +21 -21
- package/dist/contexts/held-runs.d.ts +123 -16
- package/dist/contexts/protection/aggregate.d.ts +3 -2
- package/dist/contexts/protection/branch-gate.d.ts +15 -0
- package/dist/contexts/protection/concurrency-gate.d.ts +8 -2
- package/dist/contexts/protection/pipeline.d.ts +18 -0
- package/dist/contexts/release-queued-holds.d.ts +35 -0
- package/dist/dashboard/attestation-filters.d.ts +8 -0
- package/dist/dashboard/handler.d.ts +6 -24
- package/dist/db/migrations/116_org_plan_headroom.d.ts +4 -0
- package/dist/db/migrations/117_invoke_gate_proxy_jobs.d.ts +4 -0
- package/dist/db/migrations/118_invoke_gate_scheduling.d.ts +4 -0
- package/dist/db/migrations/119_scaler_ha_ownership.d.ts +4 -0
- package/dist/db/migrations/120_cluster_settings_scaler_reaper.d.ts +4 -0
- package/dist/db/migrations/121_org_settings_allow_untrusted_dockerfile_builds.d.ts +19 -0
- package/dist/db/migrations/122_host_roster_scaler_managed.d.ts +25 -0
- package/dist/db/migrations/123_workflow_registrations_default_branch.d.ts +24 -0
- package/dist/db/migrations/124_cluster_settings_provision_backoff.d.ts +4 -0
- package/dist/db/migrations/125_org_trust_directory.d.ts +30 -0
- package/dist/db/migrations/126_held_runs_posted_pending_check.d.ts +28 -0
- package/dist/db/migrations/127_org_trust_policy_approval_expiry_seconds.d.ts +26 -0
- package/dist/db/migrations/128_execution_runs_global_eval_round.d.ts +23 -0
- package/dist/db/migrations/129_execution_runs_dispatch_routing_key.d.ts +24 -0
- package/dist/db/migrations/130_scaler_provision_outcomes.d.ts +32 -0
- package/dist/db/types.d.ts +368 -10
- package/dist/entry-helpers.d.ts +28 -0
- package/dist/events/event-emitter.d.ts +22 -0
- package/dist/events/event-router.d.ts +87 -1
- package/dist/events/types.d.ts +2 -23
- package/dist/git/credential-broker.d.ts +94 -0
- package/dist/git/inherited-secret.d.ts +24 -0
- package/dist/git/installation-token.d.ts +38 -0
- package/dist/git/job-context.d.ts +13 -0
- package/dist/index.js +324 -84
- package/dist/metrics/agent-metrics-aggregator.d.ts +2 -2
- package/dist/metrics/prometheus.d.ts +111 -3
- package/dist/oidc/oidc-mint-registration.d.ts +7 -3
- package/dist/orchestrator-core.d.ts +79 -23
- package/dist/pipeline/direct-ingress-deps.d.ts +100 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +302 -31
- package/dist/pipeline/global-eval-round.d.ts +14 -0
- package/dist/pipeline/internal-event-pipeline.d.ts +140 -0
- package/dist/pipeline/invoke-gate.d.ts +164 -0
- package/dist/pipeline/needs-scheduler.d.ts +13 -0
- package/dist/pipeline/process-webhook.d.ts +119 -31
- package/dist/pipeline/processor.d.ts +226 -21
- package/dist/pipeline/rerun.d.ts +21 -0
- package/dist/pipeline/resume-workflow.d.ts +40 -7
- package/dist/pipeline/route-or-dispatch-jobs.d.ts +9 -0
- package/dist/pipeline/security-hold-check.d.ts +217 -0
- package/dist/pipeline/undispatched-hold-checks.d.ts +23 -0
- package/dist/policy/dashboard-write-policy-listener.d.ts +62 -0
- package/dist/policy/dashboard-write-policy.d.ts +14 -0
- package/dist/provider-registry.d.ts +10 -2
- package/dist/providers/github/check-status-poster.d.ts +11 -0
- package/dist/providers/github/index.d.ts +0 -2
- package/dist/providers/github/normalizer.d.ts +3 -2
- package/dist/providers/local/normalizer.d.ts +3 -5
- package/dist/providers/universal-git/index.d.ts +11 -2
- package/dist/queue/job-queue.d.ts +43 -1
- package/dist/registration/extractor.d.ts +3 -3
- package/dist/registration/registration-index.d.ts +7 -0
- package/dist/registration/registration-store.d.ts +22 -0
- package/dist/reporting/check-run-reporter.d.ts +94 -1
- package/dist/reporting/check-run-summary.d.ts +25 -1
- package/dist/reporting/execution-tracker.d.ts +207 -2
- package/dist/reporting/run-aggregator.d.ts +4 -14
- package/dist/reporting/step-display-order.d.ts +43 -0
- package/dist/routes/admin-held-runs.d.ts +142 -0
- package/dist/routes/admin-trust-policy.d.ts +34 -6
- package/dist/routes/admin.d.ts +9 -0
- package/dist/scaler/backend-factory.d.ts +55 -0
- package/dist/scaler/bare-metal-backend.d.ts +43 -5
- package/dist/scaler/claim-store.d.ts +119 -0
- package/dist/scaler/config.d.ts +4 -0
- package/dist/scaler/container-backend.d.ts +18 -4
- package/dist/scaler/container-routing.d.ts +23 -0
- package/dist/scaler/container-spawn.d.ts +28 -0
- package/dist/scaler/event-backend.d.ts +124 -0
- package/dist/scaler/event-provision-reaper.d.ts +350 -0
- package/dist/scaler/failure-tracker.d.ts +1 -1
- package/dist/scaler/firecracker-backend.d.ts +33 -6
- package/dist/scaler/index.d.ts +11 -1
- package/dist/scaler/label-matcher.d.ts +4 -3
- package/dist/scaler/manager.d.ts +899 -72
- package/dist/scaler/resolve-container-auth.d.ts +45 -0
- package/dist/scaler/scaler-events.d.ts +11 -0
- package/dist/scaler/scaler-state-store.d.ts +294 -10
- package/dist/scaler/types.d.ts +131 -13
- package/dist/scaler/warm-pool.d.ts +132 -29
- package/dist/security/comment-handler.d.ts +50 -11
- package/dist/security/identity-link.d.ts +60 -0
- package/dist/security/lock-source.d.ts +11 -13
- package/dist/security/reduced-privilege-note.d.ts +59 -0
- package/dist/security/trust-directory-store.d.ts +233 -0
- package/dist/security/trust-policy-gate.d.ts +94 -59
- package/dist/security/trust-policy-store.d.ts +3 -0
- package/dist/security/trust-resolver.d.ts +14 -98
- package/dist/server.d.ts +11 -1
- package/dist/server.js +17671 -7350
- package/dist/stale-detector/gate-deadline-detector.d.ts +52 -0
- package/dist/stale-detector/stale-run-detector.d.ts +61 -3
- package/dist/standalone.js +24238 -13822
- package/dist/worker/in-memory-job-queue.d.ts +1 -1
- package/dist/ws/agent-handler.d.ts +28 -4
- package/dist/ws/dashboard-context-handler.d.ts +28 -4
- package/dist/ws/dashboard-global-workflows-handler.d.ts +6 -0
- package/dist/ws/failure-messages.d.ts +2 -0
- package/dist/ws/git-credential-relay.d.ts +39 -0
- package/dist/ws/oidc-token-relay.d.ts +6 -11
- package/dist/ws/platform-client.d.ts +54 -9
- package/installer-image-digests.json +3 -3
- package/package.json +24 -19
- package/sbom.spdx.json +864 -822
- package/dist/approvals/team-membership-lookup.d.ts +0 -13
- package/dist/providers/github/contributor-resolver.d.ts +0 -30
- package/dist/security/contributor-cache.d.ts +0 -83
|
@@ -5,9 +5,23 @@ import type { LockFile, WorkflowDecision } from '@kici-dev/engine';
|
|
|
5
5
|
import type { EventStore } from './event-store.js';
|
|
6
6
|
import type { EventCircuitBreaker } from './circuit-breaker.js';
|
|
7
7
|
import type { TrustStore } from './trust-store.js';
|
|
8
|
-
import type { RegistrationIndex } from '../registration/registration-index.js';
|
|
8
|
+
import type { RegisteredWorkflow, RegistrationIndex } from '../registration/registration-index.js';
|
|
9
9
|
import type { EventRouterConfig, StoredEvent } from './types.js';
|
|
10
10
|
import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
|
|
11
|
+
/**
|
|
12
|
+
* System events are exempt from the per-source event-storm rate limiter: they
|
|
13
|
+
* are orchestrator-emitted (never a user `ctx.emit`) with a bounded chain depth,
|
|
14
|
+
* so they cannot loop. Two families qualify — the `__`-prefixed workflow/
|
|
15
|
+
* job-complete events, and the reserved `kici.`-prefixed events (today: the
|
|
16
|
+
* event scaler's scale-up / scale-down), which fire on real scaling demand and
|
|
17
|
+
* must not be dropped by a 100/min bucket.
|
|
18
|
+
*
|
|
19
|
+
* "Never a user `ctx.emit`" is what the exemption rests on, and it is ENFORCED
|
|
20
|
+
* rather than assumed: both prefixes are refused at the emit path (the SDK
|
|
21
|
+
* client-side, the orchestrator's `event.emit` handler authoritatively), which
|
|
22
|
+
* is the same reservation this predicate reads.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isRateExemptEventName(eventName: string): boolean;
|
|
11
25
|
/**
|
|
12
26
|
* Input for emitting an internal event.
|
|
13
27
|
*/
|
|
@@ -34,6 +48,13 @@ export interface EventMatchContext {
|
|
|
34
48
|
repoIdentifier: string;
|
|
35
49
|
/** Provider-specific credentials captured at registration time */
|
|
36
50
|
providerContext: Record<string, unknown>;
|
|
51
|
+
/**
|
|
52
|
+
* The registration's default branch (`null` when it was never captured).
|
|
53
|
+
* A `__schedule_fire` run executes this branch's lock file, so the dispatch
|
|
54
|
+
* adapter presents it as that run's branch when a context evaluates branch
|
|
55
|
+
* restrictions.
|
|
56
|
+
*/
|
|
57
|
+
defaultBranch: string | null;
|
|
37
58
|
}
|
|
38
59
|
export interface EventRouterOptions {
|
|
39
60
|
db: Kysely<Database>;
|
|
@@ -53,6 +74,30 @@ export interface EventRouterOptions {
|
|
|
53
74
|
registrationIndex: RegistrationIndex;
|
|
54
75
|
/** Stable identifier for this orchestrator process — written into `kici_events.claimed_by` for diagnostics. */
|
|
55
76
|
nodeId: string;
|
|
77
|
+
/**
|
|
78
|
+
* Boot latch: resolves once this process can actually dispatch a matched
|
|
79
|
+
* event.
|
|
80
|
+
*
|
|
81
|
+
* `start()` runs its catch-up scan well before the dispatch dependencies are
|
|
82
|
+
* assembled (the `ProcessingDeps` bag is built at `createApp`), and a restart
|
|
83
|
+
* with a backlog is exactly when that window is loaded. Without the latch a
|
|
84
|
+
* backlogged event can spend all `maxDispatchAttempts` (default 5) inside the
|
|
85
|
+
* window — full-jitter backoff can re-fire almost immediately — and land in
|
|
86
|
+
* the DLQ, which is terminal loss.
|
|
87
|
+
*
|
|
88
|
+
* Consumed two DIFFERENT ways, because the two paths sit on opposite sides of
|
|
89
|
+
* the caller that resolves it:
|
|
90
|
+
*
|
|
91
|
+
* - **Live notification** — awaited inline, before leasing. The handler runs
|
|
92
|
+
* off the pg client's event loop, so nothing upstream is blocked.
|
|
93
|
+
* - **Catch-up** — the scan is SCHEDULED behind the latch, never awaited by
|
|
94
|
+
* `start()`. The composition root resolves the latch only after `start()`
|
|
95
|
+
* returns, so awaiting inline would be a guaranteed startup deadlock.
|
|
96
|
+
*
|
|
97
|
+
* Absent ⇒ no gating, and the catch-up runs inline exactly as before (tests,
|
|
98
|
+
* and any caller that is ready before `start()`).
|
|
99
|
+
*/
|
|
100
|
+
dispatchReady?: () => Promise<void>;
|
|
56
101
|
}
|
|
57
102
|
/**
|
|
58
103
|
* EventRouter delivers internal events to matching workflows via PostgreSQL LISTEN/NOTIFY.
|
|
@@ -75,6 +120,21 @@ export declare class EventRouter {
|
|
|
75
120
|
private readonly config;
|
|
76
121
|
private readonly clusterSettings?;
|
|
77
122
|
private readonly onEventMatched;
|
|
123
|
+
private readonly dispatchReady;
|
|
124
|
+
/** The deferred catch-up scan, when `start()` scheduled one behind the latch. */
|
|
125
|
+
private catchUpScan;
|
|
126
|
+
/**
|
|
127
|
+
* The catch-up scan ITSELF, set the moment it actually begins.
|
|
128
|
+
*
|
|
129
|
+
* Distinct from `catchUpScan`, which is the whole latch-then-scan chain.
|
|
130
|
+
* `stop()` awaits this one, never the chain: the latch is resolved by the
|
|
131
|
+
* composition root PAST `start()`, so a bootstrap that fails in between
|
|
132
|
+
* leaves it pending forever and awaiting the chain would hang shutdown.
|
|
133
|
+
* Awaiting only a scan that has begun bounds the wait by the scan.
|
|
134
|
+
*/
|
|
135
|
+
private runningCatchUp;
|
|
136
|
+
/** Set by `stop()` so a latch that resolves after shutdown starts no scan. */
|
|
137
|
+
private stopped;
|
|
78
138
|
private readonly registrationIndex;
|
|
79
139
|
private readonly nodeId;
|
|
80
140
|
private client;
|
|
@@ -85,6 +145,14 @@ export declare class EventRouter {
|
|
|
85
145
|
* Runs catch-up on start to process events missed during downtime.
|
|
86
146
|
*/
|
|
87
147
|
start(): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* The deferred catch-up scan scheduled by `start()` behind the boot latch, or
|
|
150
|
+
* `null` when the scan ran inline (no latch configured).
|
|
151
|
+
*
|
|
152
|
+
* Exposed so a caller can await the scan rather than poll for its effects.
|
|
153
|
+
* `start()` deliberately does not await it — see the comment there.
|
|
154
|
+
*/
|
|
155
|
+
get catchUpSettled(): Promise<void> | null;
|
|
88
156
|
/**
|
|
89
157
|
* Stop listening and release the dedicated pg client.
|
|
90
158
|
*/
|
|
@@ -187,6 +255,24 @@ export declare class EventRouter {
|
|
|
187
255
|
* so we wrap the stored event's metadata into the expected structure.
|
|
188
256
|
*/
|
|
189
257
|
private buildSimulatedEvent;
|
|
258
|
+
/**
|
|
259
|
+
* Match a kici event by name against the SOURCE repo's own `kiciEvent({ name })`
|
|
260
|
+
* subscribers, returning the matched decisions plus the synthetic lock file each
|
|
261
|
+
* was matched against.
|
|
262
|
+
*
|
|
263
|
+
* This reuses the exact match path `processSubscriptions` uses for a custom
|
|
264
|
+
* event — the `kici_event` index lookup plus `matchAllWorkflows` against a
|
|
265
|
+
* one-workflow synthetic lock file — but scoped to `sourceRepo` and without the
|
|
266
|
+
* async event-store round-trip, so an invoke gate can summon the repo's opt-in
|
|
267
|
+
* workflows synchronously and correlate each spawned run. The match is scoped to
|
|
268
|
+
* the source repo's own registrations (source == target), so no cross-repo trust
|
|
269
|
+
* check applies.
|
|
270
|
+
*/
|
|
271
|
+
matchKiciEventSubscribers(eventName: string, payload: Record<string, unknown>, sourceRepo: string, sourceRoutingKey?: string): Array<{
|
|
272
|
+
reg: RegisteredWorkflow;
|
|
273
|
+
lockFile: LockFile;
|
|
274
|
+
decisions: WorkflowDecision[];
|
|
275
|
+
}>;
|
|
190
276
|
/**
|
|
191
277
|
* Catch-up: process every unprocessed event missed during downtime.
|
|
192
278
|
*
|
package/dist/events/types.d.ts
CHANGED
|
@@ -36,10 +36,8 @@ export interface EventRouterConfig {
|
|
|
36
36
|
* succeeds, and lands the row in the DLQ when N exceeds
|
|
37
37
|
* `maxDispatchAttempts`.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* planted by accident. Source the value from
|
|
42
|
-
* `KICI_TEST_EVENT_FAIL_FIRST_N` (a JSON object literal).
|
|
39
|
+
* Undefined in the shipped orchestrator: only the build-time test double
|
|
40
|
+
* supplies this map, via the injected fault-injection policy.
|
|
43
41
|
*/
|
|
44
42
|
debugFailFirstNAttemptsByEvent?: Record<string, number>;
|
|
45
43
|
}
|
|
@@ -73,25 +71,6 @@ export interface StoredEvent {
|
|
|
73
71
|
dlqAt: Date | null;
|
|
74
72
|
dlqReason: DlqReason | null;
|
|
75
73
|
}
|
|
76
|
-
/**
|
|
77
|
-
* Parse the `KICI_TEST_EVENT_FAIL_FIRST_N` JSON payload, gated by
|
|
78
|
-
* `KICI_TEST_MODE`. Returns the parsed map or `undefined` when:
|
|
79
|
-
*
|
|
80
|
-
* - `testMode` is false (the master switch). The JSON value is ignored
|
|
81
|
-
* entirely; production deployments never see fault-injection even if
|
|
82
|
-
* the per-event env var is accidentally planted.
|
|
83
|
-
* - the JSON value is absent / empty.
|
|
84
|
-
* - the JSON value is malformed or carries a wrong-shape entry. We
|
|
85
|
-
* refuse to fall back to a partial map: a typo on one line silently
|
|
86
|
-
* skipping that test would be confusing in CI logs.
|
|
87
|
-
*
|
|
88
|
-
* The accepted shape is `{ "<eventName>": <number> }`; non-string keys
|
|
89
|
-
* and non-number values are rejected. The numeric value is the inclusive
|
|
90
|
-
* upper bound of attempts to fail (so `1` fails the first attempt and
|
|
91
|
-
* succeeds on retry; `99` exceeds `maxDispatchAttempts` and lands the
|
|
92
|
-
* row in the DLQ).
|
|
93
|
-
*/
|
|
94
|
-
export declare function parseFaultInjectionMap(testMode: boolean, raw: string | undefined): Record<string, number> | undefined;
|
|
95
74
|
/**
|
|
96
75
|
* Default event router configuration.
|
|
97
76
|
*/
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a git credential reference to material plus the grant it actually
|
|
3
|
+
* obtained.
|
|
4
|
+
*
|
|
5
|
+
* Two axes, deliberately orthogonal:
|
|
6
|
+
* - shape — minted (a GitHub App token) or static (PAT / Basic / SSH)
|
|
7
|
+
* - origin — a source credential the orchestrator already holds, a secret
|
|
8
|
+
* resolved from the secrets backend, or a secret output inherited
|
|
9
|
+
* from an upstream job
|
|
10
|
+
*
|
|
11
|
+
* Origin is a reference, not a third backend: all of them feed the same two
|
|
12
|
+
* shapes.
|
|
13
|
+
*
|
|
14
|
+
* The broker reports what it granted and never echoes the request. A static
|
|
15
|
+
* credential is `{ scoped: false }` because an SSH key or PAT cannot be
|
|
16
|
+
* narrowed after the fact, and recording a request as if it had been honoured
|
|
17
|
+
* would be a lie in an audit log.
|
|
18
|
+
*
|
|
19
|
+
* Knows nothing about git, clones, or agents.
|
|
20
|
+
*/
|
|
21
|
+
import type { GitCredentialRef, GitCredentialResult, ProviderGitAuth } from '@kici-dev/engine';
|
|
22
|
+
import type { SecretResolverApi } from '../secrets/secret-resolver.js';
|
|
23
|
+
import { type MintedToken } from './installation-token.js';
|
|
24
|
+
/** Injected so tests need no network and so the mint seam stays explicit. */
|
|
25
|
+
type MintFn = (args: {
|
|
26
|
+
appId: string;
|
|
27
|
+
privateKey: string;
|
|
28
|
+
installationId: string;
|
|
29
|
+
repositories: readonly string[];
|
|
30
|
+
permissions?: Readonly<Record<string, string>>;
|
|
31
|
+
}) => Promise<MintedToken>;
|
|
32
|
+
/**
|
|
33
|
+
* Reads one secret output this job inherited from a `needs` upstream. Injected
|
|
34
|
+
* rather than constructed so the broker needs no database in unit tests, and so
|
|
35
|
+
* the decryption stays in the one place that already owns it.
|
|
36
|
+
*/
|
|
37
|
+
type SecretOutputFn = (runId: string, jobId: string, key: string) => Promise<string | null>;
|
|
38
|
+
export interface BrokerResolveArgs {
|
|
39
|
+
orgId: string;
|
|
40
|
+
repositories: readonly string[];
|
|
41
|
+
/** Omit for the source credential the orchestrator already holds. */
|
|
42
|
+
ref?: GitCredentialRef;
|
|
43
|
+
permissions?: Readonly<Record<string, string>>;
|
|
44
|
+
runId?: string;
|
|
45
|
+
jobId?: string;
|
|
46
|
+
}
|
|
47
|
+
export declare class GitCredentialBroker {
|
|
48
|
+
private readonly secretResolver;
|
|
49
|
+
private readonly sourceAuth;
|
|
50
|
+
private readonly mint;
|
|
51
|
+
private readonly secretOutputs;
|
|
52
|
+
constructor(deps: {
|
|
53
|
+
secretResolver: SecretResolverApi;
|
|
54
|
+
/**
|
|
55
|
+
* Yields the source credential for a repository — normally
|
|
56
|
+
* `bundle.cloneTokenProvider.issueGitAuth(...)`. Injected rather than
|
|
57
|
+
* constructed so there is one source-credential path, not two.
|
|
58
|
+
*/
|
|
59
|
+
sourceAuth: (repository: string) => Promise<ProviderGitAuth | null>;
|
|
60
|
+
mint?: MintFn;
|
|
61
|
+
secretOutputs?: SecretOutputFn;
|
|
62
|
+
});
|
|
63
|
+
resolve(args: BrokerResolveArgs): Promise<GitCredentialResult>;
|
|
64
|
+
/**
|
|
65
|
+
* The source credential, as a ref. Delegates to the dispatch bundle's
|
|
66
|
+
* existing `CloneTokenProvider` — the same object that already mints the
|
|
67
|
+
* clone token today — so there is exactly one source-credential path, not two.
|
|
68
|
+
*
|
|
69
|
+
* It arrives as material the orchestrator already holds, so it uses the
|
|
70
|
+
* `*Value` form: there is no secret-store entry to name.
|
|
71
|
+
*/
|
|
72
|
+
private sourceRef;
|
|
73
|
+
/**
|
|
74
|
+
* Read one `<name>Secret` / `<name>Value` pair.
|
|
75
|
+
*
|
|
76
|
+
* `*Value` is material — return it verbatim. `*Secret` is a qualified
|
|
77
|
+
* `<context>:<secret-name>` reference, so the CONTEXT comes from the
|
|
78
|
+
* reference itself rather than being inferred, matching
|
|
79
|
+
* `isQualifiedSecretRef` in `packages/sdk/src/workflow.ts`.
|
|
80
|
+
*/
|
|
81
|
+
private sourced;
|
|
82
|
+
/** Route a qualified reference to the store that owns it. */
|
|
83
|
+
private resolveQualified;
|
|
84
|
+
/**
|
|
85
|
+
* Resolve a secret output this job inherited from a `needs` upstream.
|
|
86
|
+
*
|
|
87
|
+
* Reads the existing run-scoped store rather than adding a second one: the
|
|
88
|
+
* value was written by `ctx.setSecretOutput`, is encrypted at rest, and is
|
|
89
|
+
* deleted when the run completes.
|
|
90
|
+
*/
|
|
91
|
+
private resolveInherited;
|
|
92
|
+
}
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=credential-broker.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a secret output this job inherited from a `needs` upstream.
|
|
3
|
+
*
|
|
4
|
+
* Backs the reserved `needs:` context in a qualified credential reference. The
|
|
5
|
+
* value was written by `ctx.setSecretOutput`, is encrypted at rest in
|
|
6
|
+
* `run_secret_outputs`, and is deleted when the run completes — so this reads
|
|
7
|
+
* the store that already exists rather than adding a second one.
|
|
8
|
+
*/
|
|
9
|
+
import type { SecretOutputStore } from '../secrets/secret-output-store.js';
|
|
10
|
+
export interface InheritedSecretDeps {
|
|
11
|
+
secretOutputStore: SecretOutputStore;
|
|
12
|
+
/** Upstream job ids for a job, in the same shape the run merge path uses. */
|
|
13
|
+
upstreamJobIds: (runId: string, jobId: string) => Promise<string[]>;
|
|
14
|
+
/** The orchestrator's master secret key, as configured. */
|
|
15
|
+
secretKey: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build the `secretOutputs` lookup the credential broker takes.
|
|
19
|
+
*
|
|
20
|
+
* Returns null when the key was not published by any upstream — the broker
|
|
21
|
+
* turns that into an actionable error naming `setSecretOutput`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createInheritedSecretReader(deps: InheritedSecretDeps): (runId: string, jobId: string, key: string) => Promise<string | null>;
|
|
24
|
+
//# sourceMappingURL=inherited-secret.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mint a GitHub App installation access token, scoped to one repository and to
|
|
3
|
+
* an explicit permission set.
|
|
4
|
+
*
|
|
5
|
+
* Shared deliberately: both the stored KiCI App and a customer's own App
|
|
6
|
+
* (supplied through workflow secrets) mint the same way, and duplicating the
|
|
7
|
+
* JWT dance across two code paths would leave two things to keep in sync as
|
|
8
|
+
* GitHub evolves. It lives outside `providers/github/` for the same reason —
|
|
9
|
+
* the workflow-supplied path must not import a provider it is not using.
|
|
10
|
+
*
|
|
11
|
+
* Installation tokens expire after one hour and cannot be renewed, so callers
|
|
12
|
+
* must mint per use rather than caching. The credential helper does exactly
|
|
13
|
+
* that, which is what makes an arbitrarily long job's `git push` succeed.
|
|
14
|
+
*/
|
|
15
|
+
import { Octokit } from '@octokit/rest';
|
|
16
|
+
/** A freshly minted installation token and what it can actually do. */
|
|
17
|
+
export interface MintedToken {
|
|
18
|
+
token: string;
|
|
19
|
+
/** ISO-8601 expiry, or null when the forge reported none. */
|
|
20
|
+
expiresAt: string | null;
|
|
21
|
+
/** Permissions GitHub ACTUALLY granted — never an echo of the request. */
|
|
22
|
+
grantedPermissions: Readonly<Record<string, string>>;
|
|
23
|
+
repositorySelection: string;
|
|
24
|
+
}
|
|
25
|
+
export interface MintInstallationTokenArgs {
|
|
26
|
+
appId: string;
|
|
27
|
+
/** PEM-encoded App private key. */
|
|
28
|
+
privateKey: string;
|
|
29
|
+
installationId: string;
|
|
30
|
+
/** `owner/repo` for every repository the token must cover. Only the repo
|
|
31
|
+
* half of each reaches the API. At least one. */
|
|
32
|
+
repositories: readonly string[];
|
|
33
|
+
permissions?: Readonly<Record<string, string>>;
|
|
34
|
+
/** Seam for tests; production callers omit it. */
|
|
35
|
+
octokitFactory?: (appId: string, privateKey: string) => Octokit;
|
|
36
|
+
}
|
|
37
|
+
export declare function mintInstallationToken(args: MintInstallationTokenArgs): Promise<MintedToken>;
|
|
38
|
+
//# sourceMappingURL=installation-token.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-job facts the git credential relay needs, read from server truth.
|
|
3
|
+
*
|
|
4
|
+
* The relay never takes the org or the source repository from request params —
|
|
5
|
+
* an agent could name any repository it liked. Both come from the run row the
|
|
6
|
+
* orchestrator itself wrote at dispatch.
|
|
7
|
+
*/
|
|
8
|
+
import type { Kysely } from 'kysely';
|
|
9
|
+
import type { Database } from '../db/types.js';
|
|
10
|
+
import type { JobCredentialContext } from '../ws/git-credential-relay.js';
|
|
11
|
+
/** Build the `jobContext` lookup the git credential handler takes. */
|
|
12
|
+
export declare function createJobCredentialContextReader(db: Kysely<Database>): (runId: string) => Promise<JobCredentialContext | null>;
|
|
13
|
+
//# sourceMappingURL=job-context.d.ts.map
|