@kici-dev/orchestrator 0.1.26 → 0.1.27
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/app.d.ts +13 -4
- package/dist/approvals/apply-decision.d.ts +1 -1
- package/dist/approvals/step-approval-bridge.d.ts +1 -1
- package/dist/cache/pending-inits.d.ts +4 -4
- package/dist/cli/api-client.d.ts +29 -4
- package/dist/cli/commands/context.d.ts +25 -0
- package/dist/cli/commands/debug-bundle.d.ts +1 -1
- package/dist/cli/commands/variable.d.ts +6 -6
- package/dist/cli/service/windows.d.ts +6 -0
- package/dist/cli.js +526 -340
- package/dist/config.d.ts +16 -0
- package/dist/contexts/binding-store.d.ts +36 -0
- package/dist/contexts/context-store.d.ts +87 -0
- package/dist/{environments → contexts}/held-runs.d.ts +15 -15
- package/dist/{environments → contexts}/index.d.ts +1 -1
- package/dist/contexts/protection/aggregate.d.ts +43 -0
- package/dist/contexts/protection/branch-gate.d.ts +5 -0
- package/dist/contexts/protection/concurrency-gate.d.ts +7 -0
- package/dist/{environments → contexts}/protection/pipeline.d.ts +3 -3
- package/dist/contexts/protection/reviewer-gate.d.ts +7 -0
- package/dist/{environments → contexts}/protection/satisfiability.d.ts +21 -21
- package/dist/contexts/protection/trust-gate.d.ts +7 -0
- package/dist/contexts/protection/wait-timer-gate.d.ts +7 -0
- package/dist/contexts/variable-store.d.ts +39 -0
- package/dist/dashboard/attestation-filters.d.ts +10 -8
- package/dist/dashboard/handler.d.ts +28 -2
- package/dist/db/migrations/067_environments_to_contexts.d.ts +36 -0
- package/dist/db/migrations/068_request_idempotency.d.ts +17 -0
- package/dist/db/types.d.ts +78 -59
- package/dist/github-app-name-refresher/github-app-name-refresher.d.ts +1 -1
- package/dist/index.js +21 -6
- package/dist/metrics/prometheus.d.ts +2 -0
- package/dist/oidc/id-token-claims.d.ts +63 -0
- package/dist/oidc/jwt.d.ts +15 -0
- package/dist/oidc/local-dev-signer.d.ts +31 -0
- package/dist/oidc/local-mint.d.ts +77 -0
- package/dist/oidc/oidc-mint-registration.d.ts +49 -0
- package/dist/pipeline/decorating-secret-resolver.d.ts +4 -4
- package/dist/pipeline/dispatch-matched-workflow.d.ts +3 -3
- package/dist/pipeline/inline-eval.d.ts +2 -2
- package/dist/pipeline/install-secrets-resolver.d.ts +13 -13
- package/dist/pipeline/{job-environments.d.ts → job-contexts.d.ts} +23 -23
- package/dist/pipeline/manual-schedule.d.ts +8 -1
- package/dist/pipeline/processor.d.ts +6 -6
- package/dist/pipeline/request-idempotency.d.ts +28 -0
- package/dist/pipeline/rerun.d.ts +8 -0
- package/dist/pipeline/resume-workflow.d.ts +1 -1
- package/dist/pipeline/test-pipeline.d.ts +2 -2
- package/dist/provenance/trust-root.d.ts +7 -0
- package/dist/provider-registry.d.ts +8 -0
- package/dist/providers/local/index.d.ts +1 -0
- package/dist/providers/local/local-source-config.d.ts +1 -0
- package/dist/reporting/execution-tracker.d.ts +17 -7
- package/dist/reporting/run-aggregator.d.ts +5 -5
- package/dist/routes/admin-contexts.d.ts +47 -0
- package/dist/routes/admin-registrations.d.ts +2 -2
- package/dist/routes/github-webhook.d.ts +2 -2
- package/dist/secrets/context-secret-resolver.d.ts +30 -0
- package/dist/secrets/index.d.ts +1 -1
- package/dist/secrets/pg-secret-store.d.ts +3 -3
- package/dist/secrets/rbac.d.ts +1 -1
- package/dist/secrets/secret-resolver.d.ts +19 -19
- package/dist/security/comment-handler.d.ts +1 -1
- package/dist/server.js +1770 -1196
- package/dist/stale-detector/stale-run-detector.d.ts +1 -1
- package/dist/standalone.js +1649 -747
- package/dist/storage/blob-routes.d.ts +16 -0
- package/dist/ws/{dashboard-env-handler.d.ts → dashboard-context-handler.d.ts} +15 -15
- package/dist/ws/oidc-token-relay.d.ts +6 -0
- package/installer-image-digests.json +3 -3
- package/package.json +4 -4
- package/sbom.spdx.json +50 -50
- package/dist/cli/commands/environment.d.ts +0 -25
- package/dist/environments/binding-store.d.ts +0 -36
- package/dist/environments/environment-store.d.ts +0 -87
- package/dist/environments/protection/aggregate.d.ts +0 -43
- package/dist/environments/protection/branch-gate.d.ts +0 -5
- package/dist/environments/protection/concurrency-gate.d.ts +0 -7
- package/dist/environments/protection/reviewer-gate.d.ts +0 -7
- package/dist/environments/protection/trust-gate.d.ts +0 -7
- package/dist/environments/protection/wait-timer-gate.d.ts +0 -7
- package/dist/environments/variable-store.d.ts +0 -39
- package/dist/routes/admin-environments.d.ts +0 -47
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Rename the named-policy object from "environment" to "context" across the
|
|
4
|
+
* orchestrator schema. Data-preserving rename-in-place (never drop/recreate):
|
|
5
|
+
*
|
|
6
|
+
* Tables:
|
|
7
|
+
* - `environments` → `contexts`
|
|
8
|
+
* - `environment_bindings` → `context_bindings`
|
|
9
|
+
* - `environment_variables` → `context_variables`
|
|
10
|
+
* - `environment_source_overrides` → `context_source_overrides`
|
|
11
|
+
*
|
|
12
|
+
* Columns:
|
|
13
|
+
* - `context_bindings.environment_id` → `context_id`
|
|
14
|
+
* - `context_variables.environment_id` → `context_id`
|
|
15
|
+
* - `context_source_overrides.environment_id` → `context_id`
|
|
16
|
+
* - `held_runs.environment_id` → `context_id`
|
|
17
|
+
* - `execution_runs.environment` → `context`
|
|
18
|
+
* - `execution_runs.environment_id` → `context_id`
|
|
19
|
+
* - `execution_jobs.environments` → `contexts`
|
|
20
|
+
* - `execution_jobs.skipped_environments` → `skipped_contexts`
|
|
21
|
+
*
|
|
22
|
+
* Index:
|
|
23
|
+
* - `idx_execution_runs_environment_id` → `idx_execution_runs_context_id`
|
|
24
|
+
*
|
|
25
|
+
* Held-run enum values + defaults: `held_runs.queue_type` /
|
|
26
|
+
* `held_runs.trigger_source` default `'environment'` → `'context'` and existing
|
|
27
|
+
* `'environment'` rows are migrated to `'context'` (the `HeldRunQueueType` value
|
|
28
|
+
* rename).
|
|
29
|
+
*
|
|
30
|
+
* Foreign keys and remaining constraints/indexes follow the renamed tables and
|
|
31
|
+
* columns automatically (Postgres references them by identity, not name), so
|
|
32
|
+
* only the one hand-named index above needs an explicit rename.
|
|
33
|
+
*/
|
|
34
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
35
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
36
|
+
//# sourceMappingURL=067_environments_to_contexts.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Add the `request_idempotency` claim table: a `request_id`-keyed record that
|
|
4
|
+
* makes run-minting dashboard requests (`run.rerun.request`,
|
|
5
|
+
* `run.manual_schedule.request`) idempotent on the Platform `requestId`. HA
|
|
6
|
+
* coordinator siblings share one orchestrator DB, so when the Platform relay
|
|
7
|
+
* fails over and re-sends the same request to a sibling, the atomic `INSERT …
|
|
8
|
+
* ON CONFLICT DO NOTHING` on `request_id` lets exactly one coordinator win —
|
|
9
|
+
* the loser returns the winner's `new_run_id` instead of minting a second run.
|
|
10
|
+
* Rows are pruned after 1h (far past the ~10s request budget) by the periodic
|
|
11
|
+
* cleanup tick.
|
|
12
|
+
*
|
|
13
|
+
* Idempotent: guarded on table existence.
|
|
14
|
+
*/
|
|
15
|
+
export declare function up(db: Kysely<unknown>): Promise<void>;
|
|
16
|
+
export declare function down(db: Kysely<unknown>): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=068_request_idempotency.d.ts.map
|
package/dist/db/types.d.ts
CHANGED
|
@@ -13,11 +13,11 @@ export interface Database {
|
|
|
13
13
|
execution_steps: ExecutionStepTable;
|
|
14
14
|
raft_state: RaftStateTable;
|
|
15
15
|
secret_audit_log: SecretAuditLogTable;
|
|
16
|
-
|
|
16
|
+
contexts: ContextsTable;
|
|
17
17
|
scoped_secrets: ScopedSecretsTable;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
context_bindings: ContextBindingsTable;
|
|
19
|
+
context_variables: ContextVariablesTable;
|
|
20
|
+
context_source_overrides: ContextSourceOverridesTable;
|
|
21
21
|
held_runs: HeldRunsTable;
|
|
22
22
|
held_run_approvals: HeldRunApprovalsTable;
|
|
23
23
|
admin_tokens: AdminTokenTable;
|
|
@@ -52,7 +52,26 @@ export interface Database {
|
|
|
52
52
|
pending_attestations: PendingAttestationsTable;
|
|
53
53
|
remote_sources: RemoteSourcesTable;
|
|
54
54
|
host_roster: HostRosterTable;
|
|
55
|
+
request_idempotency: RequestIdempotencyTable;
|
|
55
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Request idempotency claim table.
|
|
59
|
+
* Keyed on the Platform `requestId`; makes run-minting dashboard requests
|
|
60
|
+
* (`run.rerun.request`, `run.manual_schedule.request`) idempotent across an HA
|
|
61
|
+
* relay failover so a re-sent request returns the first coordinator's
|
|
62
|
+
* `new_run_id` instead of creating a second run. Pruned after 1h.
|
|
63
|
+
*/
|
|
64
|
+
export interface RequestIdempotencyTable {
|
|
65
|
+
/** Platform-minted requestId for the run-minting request (primary key / idempotency key). */
|
|
66
|
+
request_id: string;
|
|
67
|
+
/** The run id the winning coordinator created for this requestId. */
|
|
68
|
+
new_run_id: string;
|
|
69
|
+
/** When the claim was recorded. */
|
|
70
|
+
created_at: Generated<Date>;
|
|
71
|
+
}
|
|
72
|
+
export type RequestIdempotency = Selectable<RequestIdempotencyTable>;
|
|
73
|
+
export type NewRequestIdempotency = Insertable<RequestIdempotencyTable>;
|
|
74
|
+
export type RequestIdempotencyUpdate = Updateable<RequestIdempotencyTable>;
|
|
56
75
|
/**
|
|
57
76
|
* Cluster metadata table
|
|
58
77
|
* Key-value store for cluster-wide configuration (e.g. cluster_id).
|
|
@@ -288,10 +307,10 @@ export interface ExecutionRunTable {
|
|
|
288
307
|
cancelled_by: string | null;
|
|
289
308
|
/** Agent provenance label when the run was cancelled through an agent credential (null otherwise). */
|
|
290
309
|
cancelled_by_agent_label: string | null;
|
|
291
|
-
/**
|
|
292
|
-
|
|
293
|
-
/** Matched
|
|
294
|
-
|
|
310
|
+
/** Context name for this run (null if no context applies) */
|
|
311
|
+
context: string | null;
|
|
312
|
+
/** Matched context id for this run (null if no/unresolved context). */
|
|
313
|
+
context_id: string | null;
|
|
295
314
|
/** Trust tier of the contributor for PR runs (null for non-PR events) */
|
|
296
315
|
trust_tier: string | null;
|
|
297
316
|
/** Lock file source: 'head' or 'base' (null for non-PR events) */
|
|
@@ -397,17 +416,17 @@ export interface ExecutionJobTable {
|
|
|
397
416
|
/** Aggregated step outputs JSONB (step-keyed map of outputs). Populated on job success. */
|
|
398
417
|
outputs: string | null;
|
|
399
418
|
/**
|
|
400
|
-
* Ordered bound deployment-
|
|
419
|
+
* Ordered bound deployment-context names for this job, JSON-encoded
|
|
401
420
|
* `string[]` (null when the job binds none). Written at dispatch and
|
|
402
|
-
* overwritten with the agent-resolved list for dynamic
|
|
421
|
+
* overwritten with the agent-resolved list for dynamic contexts.
|
|
403
422
|
*/
|
|
404
|
-
|
|
423
|
+
contexts: string | null;
|
|
405
424
|
/**
|
|
406
|
-
* Bound
|
|
425
|
+
* Bound contexts skipped on a test/local run (non-test or unconfigured),
|
|
407
426
|
* JSON-encoded `string[]`. NULL = nothing skipped.
|
|
408
427
|
*/
|
|
409
|
-
|
|
410
|
-
/** User-visible warning naming the skipped test-run
|
|
428
|
+
skipped_contexts: string | null;
|
|
429
|
+
/** User-visible warning naming the skipped test-run contexts. NULL = none. */
|
|
411
430
|
env_warning: string | null;
|
|
412
431
|
/** Whether all upstream needs edges are satisfied (dispatch gate). */
|
|
413
432
|
needs_satisfied: Generated<boolean>;
|
|
@@ -561,20 +580,20 @@ export interface RaftStateTable {
|
|
|
561
580
|
export type RaftState = Selectable<RaftStateTable>;
|
|
562
581
|
export type RaftStateUpdate = Updateable<RaftStateTable>;
|
|
563
582
|
/**
|
|
564
|
-
*
|
|
565
|
-
* Named deployment
|
|
583
|
+
* Contexts table
|
|
584
|
+
* Named deployment contexts with concurrency, branch restrictions, and approval rules.
|
|
566
585
|
* Scoped to an organization.
|
|
567
586
|
*/
|
|
568
|
-
export interface
|
|
587
|
+
export interface ContextsTable {
|
|
569
588
|
/** UUID primary key */
|
|
570
589
|
id: Generated<string>;
|
|
571
590
|
/** Organization ID */
|
|
572
591
|
org_id: string;
|
|
573
|
-
/**
|
|
592
|
+
/** Context name (unique within org) */
|
|
574
593
|
name: string;
|
|
575
|
-
/**
|
|
594
|
+
/** Context type: 'fixed' | 'dynamic' */
|
|
576
595
|
type: Generated<string>;
|
|
577
|
-
/** Glob pattern for dynamic
|
|
596
|
+
/** Glob pattern for dynamic contexts (null for fixed) */
|
|
578
597
|
glob_pattern: string | null;
|
|
579
598
|
/** JSONB array of branch restriction patterns */
|
|
580
599
|
branch_restrictions: Generated<string>;
|
|
@@ -596,30 +615,30 @@ export interface EnvironmentsTable {
|
|
|
596
615
|
hold_expiry_seconds: Generated<number>;
|
|
597
616
|
/** Minimum trust tier required for CI execution (null = no trust requirement) */
|
|
598
617
|
minimum_trust: string | null;
|
|
599
|
-
/** Whether this
|
|
618
|
+
/** Whether this context allows local (no-remote) executions. Default false. */
|
|
600
619
|
allow_local_execution: Generated<boolean>;
|
|
601
|
-
/** Whether this
|
|
620
|
+
/** Whether this context is active */
|
|
602
621
|
enabled: Generated<boolean>;
|
|
603
|
-
/** When this
|
|
622
|
+
/** When this context was created */
|
|
604
623
|
created_at: Generated<Date>;
|
|
605
|
-
/** When this
|
|
624
|
+
/** When this context was last updated */
|
|
606
625
|
updated_at: Generated<Date>;
|
|
607
|
-
/** Who created this
|
|
626
|
+
/** Who created this context */
|
|
608
627
|
created_by: string | null;
|
|
609
628
|
}
|
|
610
|
-
export type
|
|
611
|
-
export type
|
|
612
|
-
export type
|
|
629
|
+
export type Context = Selectable<ContextsTable>;
|
|
630
|
+
export type NewContext = Insertable<ContextsTable>;
|
|
631
|
+
export type ContextUpdate = Updateable<ContextsTable>;
|
|
613
632
|
/**
|
|
614
633
|
* Scoped secrets table
|
|
615
|
-
* Encrypted key-value pairs scoped to org + scope (e.g.
|
|
634
|
+
* Encrypted key-value pairs scoped to org + scope (e.g. context name, repo pattern).
|
|
616
635
|
*/
|
|
617
636
|
export interface ScopedSecretsTable {
|
|
618
637
|
/** UUID primary key */
|
|
619
638
|
id: Generated<string>;
|
|
620
639
|
/** Organization ID */
|
|
621
640
|
org_id: string;
|
|
622
|
-
/** Scope identifier (e.g.
|
|
641
|
+
/** Scope identifier (e.g. context name, repo pattern) */
|
|
623
642
|
scope: string;
|
|
624
643
|
/** Secret key name */
|
|
625
644
|
key: string;
|
|
@@ -638,16 +657,16 @@ export type ScopedSecret = Selectable<ScopedSecretsTable>;
|
|
|
638
657
|
export type NewScopedSecret = Insertable<ScopedSecretsTable>;
|
|
639
658
|
export type ScopedSecretUpdate = Updateable<ScopedSecretsTable>;
|
|
640
659
|
/**
|
|
641
|
-
*
|
|
642
|
-
* Links
|
|
660
|
+
* Context bindings table
|
|
661
|
+
* Links contexts to scope patterns (e.g. workflow names, repo identifiers).
|
|
643
662
|
*/
|
|
644
|
-
export interface
|
|
663
|
+
export interface ContextBindingsTable {
|
|
645
664
|
/** UUID primary key */
|
|
646
665
|
id: Generated<string>;
|
|
647
666
|
/** Organization ID */
|
|
648
667
|
org_id: string;
|
|
649
|
-
/**
|
|
650
|
-
|
|
668
|
+
/** Context ID (FK to contexts.id, cascade delete) */
|
|
669
|
+
context_id: string;
|
|
651
670
|
/** Scope pattern for matching (e.g. workflow name glob, repo pattern) */
|
|
652
671
|
scope_pattern: string;
|
|
653
672
|
/**
|
|
@@ -659,19 +678,19 @@ export interface EnvironmentBindingsTable {
|
|
|
659
678
|
/** When this binding was created */
|
|
660
679
|
created_at: Generated<Date>;
|
|
661
680
|
}
|
|
662
|
-
export type
|
|
663
|
-
export type
|
|
681
|
+
export type ContextBinding = Selectable<ContextBindingsTable>;
|
|
682
|
+
export type NewContextBinding = Insertable<ContextBindingsTable>;
|
|
664
683
|
/**
|
|
665
|
-
*
|
|
666
|
-
* Non-secret key-value pairs attached to
|
|
684
|
+
* Context variables table
|
|
685
|
+
* Non-secret key-value pairs attached to a context.
|
|
667
686
|
*/
|
|
668
|
-
export interface
|
|
687
|
+
export interface ContextVariablesTable {
|
|
669
688
|
/** UUID primary key */
|
|
670
689
|
id: Generated<string>;
|
|
671
690
|
/** Organization ID */
|
|
672
691
|
org_id: string;
|
|
673
|
-
/**
|
|
674
|
-
|
|
692
|
+
/** Context ID (FK to contexts.id, cascade delete) */
|
|
693
|
+
context_id: string;
|
|
675
694
|
/** Variable key name */
|
|
676
695
|
key: string;
|
|
677
696
|
/** Variable value */
|
|
@@ -683,20 +702,20 @@ export interface EnvironmentVariablesTable {
|
|
|
683
702
|
/** When this variable was last updated */
|
|
684
703
|
updated_at: Generated<Date>;
|
|
685
704
|
}
|
|
686
|
-
export type
|
|
687
|
-
export type
|
|
688
|
-
export type
|
|
705
|
+
export type ContextVariable = Selectable<ContextVariablesTable>;
|
|
706
|
+
export type NewContextVariable = Insertable<ContextVariablesTable>;
|
|
707
|
+
export type ContextVariableUpdate = Updateable<ContextVariablesTable>;
|
|
689
708
|
/**
|
|
690
|
-
*
|
|
691
|
-
* Per-source (routing key) variable overrides within
|
|
709
|
+
* Context source overrides table
|
|
710
|
+
* Per-source (routing key) variable overrides within a context.
|
|
692
711
|
*/
|
|
693
|
-
export interface
|
|
712
|
+
export interface ContextSourceOverridesTable {
|
|
694
713
|
/** UUID primary key */
|
|
695
714
|
id: Generated<string>;
|
|
696
715
|
/** Organization ID */
|
|
697
716
|
org_id: string;
|
|
698
|
-
/**
|
|
699
|
-
|
|
717
|
+
/** Context ID (FK to contexts.id, cascade delete) */
|
|
718
|
+
context_id: string;
|
|
700
719
|
/** Routing key for the source */
|
|
701
720
|
routing_key: string;
|
|
702
721
|
/** Override key name */
|
|
@@ -708,9 +727,9 @@ export interface EnvironmentSourceOverridesTable {
|
|
|
708
727
|
/** When this override was last updated */
|
|
709
728
|
updated_at: Generated<Date>;
|
|
710
729
|
}
|
|
711
|
-
export type
|
|
712
|
-
export type
|
|
713
|
-
export type
|
|
730
|
+
export type ContextSourceOverride = Selectable<ContextSourceOverridesTable>;
|
|
731
|
+
export type NewContextSourceOverride = Insertable<ContextSourceOverridesTable>;
|
|
732
|
+
export type ContextSourceOverrideUpdate = Updateable<ContextSourceOverridesTable>;
|
|
714
733
|
/**
|
|
715
734
|
* Held runs table
|
|
716
735
|
* Tracks runs waiting for approval, wait timer, or concurrency slot.
|
|
@@ -724,13 +743,13 @@ export interface HeldRunsTable {
|
|
|
724
743
|
run_id: string;
|
|
725
744
|
/** Job ID within the run */
|
|
726
745
|
job_id: string;
|
|
727
|
-
/**
|
|
728
|
-
|
|
746
|
+
/** Context ID (FK to contexts.id); null once the context is deleted */
|
|
747
|
+
context_id: string | null;
|
|
729
748
|
/** Hold type: 'approval' | 'wait_timer' | 'concurrency' */
|
|
730
749
|
hold_type: string;
|
|
731
750
|
/** Hold status: 'pending' | 'approved' | 'rejected' | 'expired' | 'released' */
|
|
732
751
|
status: Generated<string>;
|
|
733
|
-
/** Queue type: '
|
|
752
|
+
/** Queue type: 'context' | 'security' */
|
|
734
753
|
queue_type: Generated<string>;
|
|
735
754
|
/** Reason for hold or resolution */
|
|
736
755
|
reason: string | null;
|
|
@@ -744,13 +763,13 @@ export interface HeldRunsTable {
|
|
|
744
763
|
resolved_at: Date | null;
|
|
745
764
|
/**
|
|
746
765
|
* Hold granularity: 'workflow' | 'job' | 'step' (engine `HoldScope`).
|
|
747
|
-
* Existing
|
|
766
|
+
* Existing context holds are job-scoped, hence the 'job' default.
|
|
748
767
|
*/
|
|
749
768
|
hold_scope: Generated<string>;
|
|
750
769
|
/** Step index within the job for step-scoped holds; null otherwise. */
|
|
751
770
|
step_index: number | null;
|
|
752
771
|
/**
|
|
753
|
-
* What created the hold: '
|
|
772
|
+
* What created the hold: 'context' (mandatory env policy) | 'explicit'
|
|
754
773
|
* (SDK `approval`). Engine `TriggerSource`.
|
|
755
774
|
*/
|
|
756
775
|
trigger_source: Generated<string>;
|
|
@@ -1303,7 +1322,7 @@ export interface SourcesTable {
|
|
|
1303
1322
|
* is the source of truth for both `name` and `slug` on GitHub-App sources.
|
|
1304
1323
|
*/
|
|
1305
1324
|
slug: string | null;
|
|
1306
|
-
/** Customer/org identifier for secret and
|
|
1325
|
+
/** Customer/org identifier for secret and context scoping */
|
|
1307
1326
|
customer_id: Generated<string>;
|
|
1308
1327
|
/** When this source was created */
|
|
1309
1328
|
created_at: Generated<Date>;
|
|
@@ -25,7 +25,7 @@ export interface RefreshableSourceStore {
|
|
|
25
25
|
}>>;
|
|
26
26
|
getSourceWithSecrets(routingKey: string): Promise<{
|
|
27
27
|
provider: string;
|
|
28
|
-
config: string
|
|
28
|
+
config: string | Record<string, unknown>;
|
|
29
29
|
privateKey: string;
|
|
30
30
|
} | null>;
|
|
31
31
|
updateSource(routingKey: string, updates: {
|
package/dist/index.js
CHANGED
|
@@ -1574,20 +1574,35 @@ var AdminApiClient = class {
|
|
|
1574
1574
|
async deleteSecret(orgId, scope, key) {
|
|
1575
1575
|
return this.request("DELETE", `/api/v1/admin/secrets/${encodeURIComponent(orgId)}/${encodeURIComponent(scope)}/${encodeURIComponent(key)}`);
|
|
1576
1576
|
}
|
|
1577
|
-
|
|
1577
|
+
/**
|
|
1578
|
+
* Create (or upsert) a deployment context. `allowLocalExecution` lets
|
|
1579
|
+
* CLI-initiated / local runs resolve secrets through this context.
|
|
1580
|
+
*/
|
|
1581
|
+
async createContext(data) {
|
|
1582
|
+
return this.request("POST", `/api/v1/admin/contexts`, data);
|
|
1583
|
+
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Bind a scope pattern to a context so its scoped secrets resolve at dispatch.
|
|
1586
|
+
* `hostPattern` defaults to `**` (every host) server-side.
|
|
1587
|
+
*/
|
|
1588
|
+
async bindContext(data) {
|
|
1589
|
+
const { name, ...body } = data;
|
|
1590
|
+
return this.request("POST", `/api/v1/admin/contexts/${encodeURIComponent(name)}/bind`, body);
|
|
1591
|
+
}
|
|
1592
|
+
async listVariables(orgId, context) {
|
|
1578
1593
|
const params = new URLSearchParams({ orgId });
|
|
1579
|
-
return this.request("GET", `/api/v1/admin/
|
|
1594
|
+
return this.request("GET", `/api/v1/admin/contexts/${encodeURIComponent(context)}/variables?${params}`);
|
|
1580
1595
|
}
|
|
1581
|
-
async setVariable(orgId,
|
|
1596
|
+
async setVariable(orgId, context, key, value, locked) {
|
|
1582
1597
|
const params = new URLSearchParams({ orgId });
|
|
1583
|
-
return this.request("PUT", `/api/v1/admin/
|
|
1598
|
+
return this.request("PUT", `/api/v1/admin/contexts/${encodeURIComponent(context)}/variables/${encodeURIComponent(key)}?${params}`, {
|
|
1584
1599
|
value,
|
|
1585
1600
|
locked
|
|
1586
1601
|
});
|
|
1587
1602
|
}
|
|
1588
|
-
async deleteVariable(orgId,
|
|
1603
|
+
async deleteVariable(orgId, context, key) {
|
|
1589
1604
|
const params = new URLSearchParams({ orgId });
|
|
1590
|
-
return this.request("DELETE", `/api/v1/admin/
|
|
1605
|
+
return this.request("DELETE", `/api/v1/admin/contexts/${encodeURIComponent(context)}/variables/${encodeURIComponent(key)}?${params}`);
|
|
1591
1606
|
}
|
|
1592
1607
|
async rotateKey() {
|
|
1593
1608
|
return this.request("POST", "/api/v1/admin/rotate-key");
|
|
@@ -12,6 +12,8 @@ export declare function setPendingAttestations(value: number): void;
|
|
|
12
12
|
export declare function setPendingAttestationOldestAgeSeconds(value: number): void;
|
|
13
13
|
/** Set the current number of terminally-rejected deferred attestations. */
|
|
14
14
|
export declare function setRejectedAttestations(value: number): void;
|
|
15
|
+
/** Record the collation-drift flag (1 = drift, 0 = clean) for a database. */
|
|
16
|
+
export declare function setDbCollationDrift(database: string, drifted: boolean): void;
|
|
15
17
|
interface ScalerUsageRow {
|
|
16
18
|
scaler: string;
|
|
17
19
|
/** Backend type for this scaler (rollup dimension). `__global__` for the orchestrator-wide row. */
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC ID-token claims for the local dev-signed identity. Mirrors the Platform's
|
|
3
|
+
* `oidc/id-token-claims.ts` so a dev-signed bundle carries the exact same claim
|
|
4
|
+
* shape the agent's statement builder + the engine verifier already expect — the
|
|
5
|
+
* cross-check between the in-toto statement and the token claims is identical to
|
|
6
|
+
* the Platform-minted path. The only differences are the local sentinel issuer
|
|
7
|
+
* (`kici-local`) and the org anchor (`__default__`, the plane's default org).
|
|
8
|
+
*/
|
|
9
|
+
import { AttestationOrigin, SourceOrigin } from '@kici-dev/engine';
|
|
10
|
+
/** The subset of an execution_runs row the claims need. */
|
|
11
|
+
export interface RunClaimSource {
|
|
12
|
+
run_id: string;
|
|
13
|
+
org_id: string;
|
|
14
|
+
repo_identifier: string | null;
|
|
15
|
+
ref: string | null;
|
|
16
|
+
sha: string | null;
|
|
17
|
+
workflow_name: string | null;
|
|
18
|
+
provider: string | null;
|
|
19
|
+
/** True when the run executed an uploaded local working tree (`kici run remote`). */
|
|
20
|
+
local_working_tree: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** The subset of an execution_jobs row the claims need. */
|
|
23
|
+
export interface JobClaimSource {
|
|
24
|
+
run_id: string;
|
|
25
|
+
job_id: string;
|
|
26
|
+
orchestrator_id: string | null;
|
|
27
|
+
status: string;
|
|
28
|
+
}
|
|
29
|
+
export interface BuildClaimsOpts {
|
|
30
|
+
issuer: string;
|
|
31
|
+
audience: string;
|
|
32
|
+
nowSeconds: number;
|
|
33
|
+
ttlSeconds: number;
|
|
34
|
+
}
|
|
35
|
+
export interface IdTokenClaims {
|
|
36
|
+
iss: string;
|
|
37
|
+
sub: string;
|
|
38
|
+
aud: string;
|
|
39
|
+
iat: number;
|
|
40
|
+
nbf: number;
|
|
41
|
+
exp: number;
|
|
42
|
+
jti: string;
|
|
43
|
+
kici_run_id: string;
|
|
44
|
+
kici_job_id: string;
|
|
45
|
+
repository: string | null;
|
|
46
|
+
ref: string | null;
|
|
47
|
+
sha: string | null;
|
|
48
|
+
workflow_ref: string | null;
|
|
49
|
+
orchestrator_id: string | null;
|
|
50
|
+
org_id: string;
|
|
51
|
+
source_origin: SourceOrigin;
|
|
52
|
+
provider: string | null;
|
|
53
|
+
statement_hash: string | null;
|
|
54
|
+
attestation_origin: AttestationOrigin;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build the OIDC ID-token claims for a build job from the orchestrator's own
|
|
58
|
+
* execution_runs/execution_jobs rows. The local dev plane only ever mints for a
|
|
59
|
+
* live (running) job, so `attestation_origin` is always `live` and
|
|
60
|
+
* `statement_hash` is null (the statement is cross-checked field-by-field).
|
|
61
|
+
*/
|
|
62
|
+
export declare function buildIdTokenClaims(run: RunClaimSource, job: JobClaimSource, opts: BuildClaimsOpts): IdTokenClaims;
|
|
63
|
+
//# sourceMappingURL=id-token-claims.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact-JWS assembly for the local dev-signed identity. Mirrors the Platform's
|
|
3
|
+
* `oidc/jwt.ts`: `jose.SignJWT` wants a local KeyLike, but our `LocalSigner`
|
|
4
|
+
* returns the JOSE-raw r||s ES256 signature directly, so we base64url-assemble
|
|
5
|
+
* the compact JWS (`header.payload.signature`) by hand.
|
|
6
|
+
*/
|
|
7
|
+
import type { LocalSigner } from './local-dev-signer.js';
|
|
8
|
+
export interface JwsProtectedHeader {
|
|
9
|
+
alg: 'ES256';
|
|
10
|
+
kid: string;
|
|
11
|
+
typ: 'JWT';
|
|
12
|
+
}
|
|
13
|
+
/** Assemble a compact JWS from a protected header + payload, signed by `signer`. */
|
|
14
|
+
export declare function signCompactJws(signer: LocalSigner, protectedHeader: JwsProtectedHeader, payload: Record<string, unknown>): Promise<string>;
|
|
15
|
+
//# sourceMappingURL=jwt.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type JWK } from 'jose';
|
|
2
|
+
/** The fixed, non-prod dev-identity issuer. Never `https://api.kici.dev`. */
|
|
3
|
+
export declare const KICI_LOCAL_ISSUER = "kici-local";
|
|
4
|
+
/** Minimal signing seam mirrored from the Platform's `Signer` idiom. */
|
|
5
|
+
export interface LocalSigner {
|
|
6
|
+
readonly alg: 'ES256';
|
|
7
|
+
/** Sign `data`, returning the JOSE-raw (r||s) ES256 signature. */
|
|
8
|
+
sign(data: Uint8Array): Promise<Uint8Array>;
|
|
9
|
+
/** The public key as a JWK (kty EC, crv P-256, alg ES256, use sig, kid). */
|
|
10
|
+
getPublicJwk(): JWK;
|
|
11
|
+
/** RFC 7638 thumbprint of the public JWK — the token-header `kid`. */
|
|
12
|
+
getKid(): string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* In-process ES256 signer over a persisted EC P-256 private JWK. NEVER selected
|
|
16
|
+
* in a Platform-connected deployment; the local dev plane is its only caller.
|
|
17
|
+
*/
|
|
18
|
+
export declare class LocalDevSigner implements LocalSigner {
|
|
19
|
+
private readonly privateKey;
|
|
20
|
+
private readonly publicJwk;
|
|
21
|
+
readonly alg: "ES256";
|
|
22
|
+
private constructor();
|
|
23
|
+
/** Build a signer from an EC P-256 private JWK (`{ kty, crv, x, y, d }`). */
|
|
24
|
+
static fromPrivateJwk(jwk: JWK): Promise<LocalDevSigner>;
|
|
25
|
+
/** Read + import the private JWK from `path` (the plane's 0600 key file). */
|
|
26
|
+
static fromFile(path: string): Promise<LocalDevSigner>;
|
|
27
|
+
sign(data: Uint8Array): Promise<Uint8Array>;
|
|
28
|
+
getPublicJwk(): JWK;
|
|
29
|
+
getKid(): string;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=local-dev-signer.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local dev-signed OIDC mint (independent mode only).
|
|
3
|
+
*
|
|
4
|
+
* The Platform-connected orchestrator relays `oidc.token.request` to the hosted
|
|
5
|
+
* Platform, which reads its own run/job rows and mints (`ws/oidc-token-relay.ts`
|
|
6
|
+
* → `oidc.mint.request`). The offline local dev plane has no Platform, so this
|
|
7
|
+
* module mints locally: it reads the orchestrator's OWN execution_runs/
|
|
8
|
+
* execution_jobs rows and signs claims with the in-process `LocalDevSigner`,
|
|
9
|
+
* issuer `kici-local`.
|
|
10
|
+
*
|
|
11
|
+
* Security: this path is registered ONLY when the orchestrator runs in
|
|
12
|
+
* `independent` mode with a `LocalDevSigner` present, and app.ts registers the
|
|
13
|
+
* Platform relay in preference (the local path is registered strictly in the
|
|
14
|
+
* `else` branch), so a Platform-connected orchestrator can never reach the local
|
|
15
|
+
* signer — it keeps minting via the Platform exactly as today. The agent never
|
|
16
|
+
* asserts its own claims; every identity claim is read server-side from the
|
|
17
|
+
* orchestrator's rows, and the job-ownership check is against dispatch state.
|
|
18
|
+
*/
|
|
19
|
+
import type { Kysely } from 'kysely';
|
|
20
|
+
import { type OidcTokenResult } from '@kici-dev/engine/protocol/messages/oidc-token-relay';
|
|
21
|
+
import type { Database } from '../db/types.js';
|
|
22
|
+
import { type IdTokenClaims } from './id-token-claims.js';
|
|
23
|
+
import { type LocalSigner } from './local-dev-signer.js';
|
|
24
|
+
/** ID-token lifetime (seconds). Matches the Platform's 10-minute cap. */
|
|
25
|
+
export declare const LOCAL_ID_TOKEN_TTL_SECONDS = 600;
|
|
26
|
+
/** The org anchor stamped into a local-plane token (the plane's default org). */
|
|
27
|
+
export declare const LOCAL_ORG_ID = "__default__";
|
|
28
|
+
export declare class LocalMintRunNotFoundError extends Error {
|
|
29
|
+
}
|
|
30
|
+
export declare class LocalMintJobNotFoundError extends Error {
|
|
31
|
+
}
|
|
32
|
+
export declare class LocalMintJobNotActiveError extends Error {
|
|
33
|
+
}
|
|
34
|
+
export interface LocalMintDeps {
|
|
35
|
+
db: Kysely<Database>;
|
|
36
|
+
signer: LocalSigner;
|
|
37
|
+
orchestratorId: string;
|
|
38
|
+
/** Injectable clock (seconds). Defaults to wall-clock. */
|
|
39
|
+
nowSeconds?: () => number;
|
|
40
|
+
}
|
|
41
|
+
export interface LocalMintInput {
|
|
42
|
+
runId: string;
|
|
43
|
+
jobId: string;
|
|
44
|
+
audience: string;
|
|
45
|
+
}
|
|
46
|
+
export interface LocalMintResult {
|
|
47
|
+
token: string;
|
|
48
|
+
expiresIn: number;
|
|
49
|
+
jti: string;
|
|
50
|
+
claims: IdTokenClaims;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Mint a short-lived dev-signed ES256 ID token for (run, job). Every identity
|
|
54
|
+
* claim is read from the orchestrator's own run/job rows; the token is never
|
|
55
|
+
* logged.
|
|
56
|
+
*/
|
|
57
|
+
export declare function mintLocalIdToken(deps: LocalMintDeps, input: LocalMintInput): Promise<LocalMintResult>;
|
|
58
|
+
/** Job-ownership resolver surface (the dispatcher's `resolveOwnedJob`). */
|
|
59
|
+
export interface LocalMintOwnershipResolver {
|
|
60
|
+
resolveOwnedJob(agentId: string, jobId: string): {
|
|
61
|
+
runId: string;
|
|
62
|
+
} | undefined;
|
|
63
|
+
}
|
|
64
|
+
export declare class LocalMintRejectedError extends Error {
|
|
65
|
+
}
|
|
66
|
+
export interface LocalOidcTokenHandlerDeps {
|
|
67
|
+
dispatcher: LocalMintOwnershipResolver;
|
|
68
|
+
mint: LocalMintDeps;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Build the agent.api handler for `OIDC_TOKEN_REQUEST_METHOD` in independent
|
|
72
|
+
* mode. Verifies the agent owns the named job (resolving its runId from the
|
|
73
|
+
* dispatcher — never trusting an agent-asserted value), then mints locally. A
|
|
74
|
+
* job the agent does not own is rejected without minting anything.
|
|
75
|
+
*/
|
|
76
|
+
export declare function createLocalOidcTokenHandler(deps: LocalOidcTokenHandlerDeps): (agentId: string, params: Record<string, unknown>) => Promise<OidcTokenResult>;
|
|
77
|
+
//# sourceMappingURL=local-mint.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Selects which OIDC-mint handler backs `OIDC_TOKEN_REQUEST_METHOD` — the
|
|
3
|
+
* anti-forgery choke point for dev-signed identity.
|
|
4
|
+
*
|
|
5
|
+
* The rule (enforced here, unit-tested in `oidc-mint-registration.test.ts`):
|
|
6
|
+
*
|
|
7
|
+
* 1. **Platform-connected** (platformUrl + token + client) → the **relay**
|
|
8
|
+
* handler, minting via the hosted Platform exactly as today.
|
|
9
|
+
* 2. **Offline local dev plane** (independent identity + a local signer, AND
|
|
10
|
+
* NOT Platform-connected) → the **local** dev-signed handler (`kici-local`).
|
|
11
|
+
* 3. Neither → **no** registration (the method returns "unknown method").
|
|
12
|
+
*
|
|
13
|
+
* Case 1 is checked FIRST, so the local signer is UNREACHABLE whenever a
|
|
14
|
+
* Platform connection exists — even if `KICI_INDEPENDENT_IDENTITY` is somehow
|
|
15
|
+
* also set. This guarantees no new forgeable mint path appears on a
|
|
16
|
+
* Platform-connected orchestrator.
|
|
17
|
+
*/
|
|
18
|
+
import type { Kysely } from 'kysely';
|
|
19
|
+
import type { OidcTokenResult } from '@kici-dev/engine/protocol/messages/oidc-token-relay';
|
|
20
|
+
import type { Database } from '../db/types.js';
|
|
21
|
+
import { type MintPlatformClient } from '../ws/oidc-token-relay.js';
|
|
22
|
+
import { type LocalMintOwnershipResolver } from './local-mint.js';
|
|
23
|
+
import type { LocalSigner } from './local-dev-signer.js';
|
|
24
|
+
export type OidcMintHandler = (agentId: string, params: Record<string, unknown>) => Promise<OidcTokenResult>;
|
|
25
|
+
export interface OidcMintRegistration {
|
|
26
|
+
/** `relay` = Platform-minted; `local` = offline dev-signed (`kici-local`). */
|
|
27
|
+
kind: 'relay' | 'local';
|
|
28
|
+
handler: OidcMintHandler;
|
|
29
|
+
}
|
|
30
|
+
export interface OidcMintRegistrationInput {
|
|
31
|
+
platformUrl?: string;
|
|
32
|
+
platformToken?: string;
|
|
33
|
+
platformClient?: MintPlatformClient;
|
|
34
|
+
independentIdentity: boolean;
|
|
35
|
+
localOidcSigner?: LocalSigner;
|
|
36
|
+
dispatcher: LocalMintOwnershipResolver & {
|
|
37
|
+
resolveOwnedJob(agentId: string, jobId: string): {
|
|
38
|
+
runId: string;
|
|
39
|
+
} | undefined;
|
|
40
|
+
};
|
|
41
|
+
db: Kysely<Database>;
|
|
42
|
+
orchestratorId: string;
|
|
43
|
+
testMode: boolean;
|
|
44
|
+
testMintDeferAudience?: string;
|
|
45
|
+
testMintRejectAudience?: string;
|
|
46
|
+
}
|
|
47
|
+
/** Decide which mint handler (if any) backs `OIDC_TOKEN_REQUEST_METHOD`. */
|
|
48
|
+
export declare function selectOidcMintRegistration(input: OidcMintRegistrationInput): OidcMintRegistration | undefined;
|
|
49
|
+
//# sourceMappingURL=oidc-mint-registration.d.ts.map
|