@kici-dev/orchestrator 0.16.0 → 0.17.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/approvals/apply-decision.d.ts +12 -1
- package/dist/cli/api-client.d.ts +8 -0
- package/dist/cli/commands/api-key.d.ts +11 -4
- package/dist/cli.js +25 -25
- package/dist/index.js +11 -4
- package/dist/pipeline/test-pipeline.d.ts +8 -7
- package/dist/queue/terminalize-unroutable.d.ts +5 -0
- package/dist/routes/admin-auth.d.ts +2 -0
- package/dist/routes/caller-identity.d.ts +52 -0
- package/dist/routes/test-direct.d.ts +46 -0
- package/dist/routes/uploads.d.ts +12 -11
- package/dist/secrets/rbac.d.ts +5 -1
- package/dist/secrets/routing-key-scope.d.ts +1 -0
- package/dist/secrets/token-manager.d.ts +1 -0
- package/dist/server.js +4477 -4126
- package/dist/standalone.js +2340 -1259
- package/dist/storage/s3.d.ts +7 -7
- package/dist/storage/types.d.ts +4 -4
- package/dist/ws/test-relay-handlers.d.ts +16 -9
- package/installer-image-digests.json +3 -3
- package/package.json +4 -4
- package/sbom.spdx.json +53 -53
- package/dist/scaler/container-spawn.d.ts +0 -28
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import { ApprovalDecision } from '@kici-dev/engine';
|
|
1
|
+
import { AccessLogAction, ApprovalDecision } from '@kici-dev/engine';
|
|
2
2
|
import type { HeldRun } from '../db/types.js';
|
|
3
3
|
import { HoldOutcome } from '../pipeline/security-hold-check.js';
|
|
4
4
|
import type { HeldRunStore, ReleaseSignal } from '../contexts/held-runs.js';
|
|
5
5
|
import { type TeamMembershipLookup } from './approval-resolver.js';
|
|
6
|
+
/**
|
|
7
|
+
* The access-log action a held-run decision is audited under.
|
|
8
|
+
*
|
|
9
|
+
* A `kici run --approve-all` breakglass approval audits as
|
|
10
|
+
* `held_run.auto_approve`, so the trail shows "auto-approved by the dispatcher"
|
|
11
|
+
* apart from an interactive approve. The marker only renames the record:
|
|
12
|
+
* eligibility is enforced the same way for both. It never applies to a reject.
|
|
13
|
+
* Every approving surface takes its action from here, so the Platform-relayed
|
|
14
|
+
* and the direct admin-route approvals cannot audit the same act two ways.
|
|
15
|
+
*/
|
|
16
|
+
export declare function heldRunDecisionAction(decision: ApprovalDecision, autoApprove: boolean): AccessLogAction;
|
|
6
17
|
/** Whether a decision's post-commit consequence ran to completion. */
|
|
7
18
|
export interface DecisionConsequenceResult {
|
|
8
19
|
/** True when the whole consequence chain ran; false when a step of it threw. */
|
package/dist/cli/api-client.d.ts
CHANGED
|
@@ -469,6 +469,10 @@ export declare class AdminApiClient {
|
|
|
469
469
|
vmIds: string[];
|
|
470
470
|
timeoutMs?: number;
|
|
471
471
|
}): Promise<ScalerOrphansStopResponse>;
|
|
472
|
+
/**
|
|
473
|
+
* @deprecated No KiCI server serves `/api/v1/api-keys`; use `createToken`
|
|
474
|
+
* (`kici-admin token create`). Removed in v1.0.0.
|
|
475
|
+
*/
|
|
472
476
|
createApiKey(opts: {
|
|
473
477
|
label?: string;
|
|
474
478
|
routingKeys?: string[];
|
|
@@ -477,6 +481,10 @@ export declare class AdminApiClient {
|
|
|
477
481
|
key: string;
|
|
478
482
|
routingKeys: string[];
|
|
479
483
|
}>;
|
|
484
|
+
/**
|
|
485
|
+
* @deprecated No KiCI server serves `/api/v1/api-keys`; use `createToken`
|
|
486
|
+
* with `routingKey` (`kici-admin token create --routing-key`). Removed in v1.0.0.
|
|
487
|
+
*/
|
|
480
488
|
addRoutingKeyPermission(keyId: string, pattern: string): Promise<{
|
|
481
489
|
id: string;
|
|
482
490
|
pattern: string;
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* `kici-admin api-key` — deprecated.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The group targeted `/api/v1/api-keys`, which no KiCI server serves, so it
|
|
5
|
+
* never worked. Both subcommands stay registered until v1.0.0 and exit with a
|
|
6
|
+
* message that points at `kici-admin token create`, the per-person
|
|
7
|
+
* orchestrator token a developer passes to `kici connect`.
|
|
6
8
|
*
|
|
7
9
|
* api-key create, add-routing-key
|
|
8
10
|
*/
|
|
9
11
|
import type { Command } from 'commander';
|
|
10
12
|
import type { AdminApiClient } from '../api-client.js';
|
|
11
|
-
export declare
|
|
13
|
+
export declare const API_KEY_DEPRECATED_MESSAGE: string;
|
|
14
|
+
/**
|
|
15
|
+
* Register the deprecated `api-key` group. `getClient` is accepted for the
|
|
16
|
+
* registration signature every command group shares and is never called.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerApiKeyCommands(program: Command, _getClient: () => AdminApiClient): void;
|
|
12
19
|
//# sourceMappingURL=api-key.d.ts.map
|
package/dist/cli.js
CHANGED
|
@@ -517,9 +517,17 @@ var AdminApiClient = class {
|
|
|
517
517
|
async stopScalerOrphans(body) {
|
|
518
518
|
return this.request("POST", "/api/v1/admin/scaler/orphans/stop", body);
|
|
519
519
|
}
|
|
520
|
+
/**
|
|
521
|
+
* @deprecated No KiCI server serves `/api/v1/api-keys`; use `createToken`
|
|
522
|
+
* (`kici-admin token create`). Removed in v1.0.0.
|
|
523
|
+
*/
|
|
520
524
|
async createApiKey(opts) {
|
|
521
525
|
return this.request("POST", "/api/v1/api-keys", opts);
|
|
522
526
|
}
|
|
527
|
+
/**
|
|
528
|
+
* @deprecated No KiCI server serves `/api/v1/api-keys`; use `createToken`
|
|
529
|
+
* with `routingKey` (`kici-admin token create --routing-key`). Removed in v1.0.0.
|
|
530
|
+
*/
|
|
523
531
|
async addRoutingKeyPermission(keyId, pattern) {
|
|
524
532
|
return this.request("POST", `/api/v1/api-keys/${encodeURIComponent(keyId)}/routing-permissions`, { pattern });
|
|
525
533
|
}
|
|
@@ -1364,26 +1372,19 @@ function registerAgentCommands(program, getClient) {
|
|
|
1364
1372
|
}
|
|
1365
1373
|
//#endregion
|
|
1366
1374
|
//#region src/cli/commands/api-key.ts
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
console.log(`Key: ${result.key}`);
|
|
1378
|
-
if (result.routingKeys?.length) console.log(`Routing keys: ${result.routingKeys.join(", ")}`);
|
|
1379
|
-
console.log("");
|
|
1380
|
-
console.log("WARNING: Save this key now -- it cannot be recovered after this point.");
|
|
1375
|
+
const API_KEY_DEPRECATED_MESSAGE = "kici-admin api-key is deprecated and has no effect: no KiCI server serves /api/v1/api-keys. Mint a per-person orchestrator token instead: kici-admin token create <label> --role admin --subject <who> --expires <duration>. This command is removed in v1.0.0.";
|
|
1376
|
+
const DEPRECATED_DESCRIPTION = "Deprecated: use kici-admin token create (removed in v1.0.0)";
|
|
1377
|
+
/**
|
|
1378
|
+
* Register the deprecated `api-key` group. `getClient` is accepted for the
|
|
1379
|
+
* registration signature every command group shares and is never called.
|
|
1380
|
+
*/
|
|
1381
|
+
function registerApiKeyCommands(program, _getClient) {
|
|
1382
|
+
const apiKey = program.command("api-key").description(DEPRECATED_DESCRIPTION);
|
|
1383
|
+
apiKey.command("create").description(DEPRECATED_DESCRIPTION).option("--label <label>", "Ignored", "unnamed").option("--routing-keys <keys>", "Ignored").action(cliAction(async () => {
|
|
1384
|
+
throw new Error(API_KEY_DEPRECATED_MESSAGE);
|
|
1381
1385
|
}));
|
|
1382
|
-
apiKey.command("add-routing-key <id> <pattern>").description(
|
|
1383
|
-
|
|
1384
|
-
console.log(`Routing key permission added.`);
|
|
1385
|
-
console.log(`Permission ID: ${result.id}`);
|
|
1386
|
-
console.log(`Pattern: ${result.pattern}`);
|
|
1386
|
+
apiKey.command("add-routing-key <id> <pattern>").description(DEPRECATED_DESCRIPTION).action(cliAction(async () => {
|
|
1387
|
+
throw new Error(API_KEY_DEPRECATED_MESSAGE);
|
|
1387
1388
|
}));
|
|
1388
1389
|
}
|
|
1389
1390
|
//#endregion
|
|
@@ -22078,7 +22079,7 @@ var S3CacheStorage = class {
|
|
|
22078
22079
|
client;
|
|
22079
22080
|
/** Separate client for pre-signed URL generation (uses externalEndpoint if configured). */
|
|
22080
22081
|
presignClient;
|
|
22081
|
-
/**
|
|
22082
|
+
/** Client for the developer upload URL: uploadEndpoint, else the presign client. */
|
|
22082
22083
|
uploadPresignClient;
|
|
22083
22084
|
bucket;
|
|
22084
22085
|
prefix;
|
|
@@ -22098,11 +22099,10 @@ var S3CacheStorage = class {
|
|
|
22098
22099
|
endpoint: options.externalEndpoint
|
|
22099
22100
|
});
|
|
22100
22101
|
else this.presignClient = this.client;
|
|
22101
|
-
|
|
22102
|
+
this.uploadPresignClient = options.uploadEndpoint ? createS3Client({
|
|
22102
22103
|
...options,
|
|
22103
22104
|
endpoint: options.uploadEndpoint
|
|
22104
|
-
});
|
|
22105
|
-
else this.uploadPresignClient = this.client;
|
|
22105
|
+
}) : this.presignClient;
|
|
22106
22106
|
}
|
|
22107
22107
|
/** Build the full S3 object key from a cache key. */
|
|
22108
22108
|
objectKey(key) {
|
|
@@ -27534,7 +27534,7 @@ init_manifest();
|
|
|
27534
27534
|
const ALL_PLATFORMS = AgentPlatform.options;
|
|
27535
27535
|
/** The orchestrator's own version (single-version invariant) = the packaged agent version. */
|
|
27536
27536
|
function resolveKiciVersion() {
|
|
27537
|
-
return "0.
|
|
27537
|
+
return "0.17.0";
|
|
27538
27538
|
}
|
|
27539
27539
|
/** Parse the --platform value: default set | single | CSV | `all`. */
|
|
27540
27540
|
function parsePlatforms(raw) {
|
|
@@ -38830,7 +38830,7 @@ function routeRootArgs(root, args) {
|
|
|
38830
38830
|
* where no bundler substituted the constant — the same shape `server.ts` and
|
|
38831
38831
|
* `standalone.ts` use for `ORCHESTRATOR_VERSION`.
|
|
38832
38832
|
*/
|
|
38833
|
-
const CLI_VERSION = "0.
|
|
38833
|
+
const CLI_VERSION = "0.17.0";
|
|
38834
38834
|
/**
|
|
38835
38835
|
* The kici-admin root command: a Commander `Command` whose own option parsing
|
|
38836
38836
|
* first routes the argv through {@link routeRootArgs}. A leading `--version`
|
package/dist/index.js
CHANGED
|
@@ -43,7 +43,7 @@ var S3CacheStorage = class {
|
|
|
43
43
|
client;
|
|
44
44
|
/** Separate client for pre-signed URL generation (uses externalEndpoint if configured). */
|
|
45
45
|
presignClient;
|
|
46
|
-
/**
|
|
46
|
+
/** Client for the developer upload URL: uploadEndpoint, else the presign client. */
|
|
47
47
|
uploadPresignClient;
|
|
48
48
|
bucket;
|
|
49
49
|
prefix;
|
|
@@ -63,11 +63,10 @@ var S3CacheStorage = class {
|
|
|
63
63
|
endpoint: options.externalEndpoint
|
|
64
64
|
});
|
|
65
65
|
else this.presignClient = this.client;
|
|
66
|
-
|
|
66
|
+
this.uploadPresignClient = options.uploadEndpoint ? createS3Client({
|
|
67
67
|
...options,
|
|
68
68
|
endpoint: options.uploadEndpoint
|
|
69
|
-
});
|
|
70
|
-
else this.uploadPresignClient = this.client;
|
|
69
|
+
}) : this.presignClient;
|
|
71
70
|
}
|
|
72
71
|
/** Build the full S3 object key from a cache key. */
|
|
73
72
|
objectKey(key) {
|
|
@@ -2978,9 +2977,17 @@ var AdminApiClient = class {
|
|
|
2978
2977
|
async stopScalerOrphans(body) {
|
|
2979
2978
|
return this.request("POST", "/api/v1/admin/scaler/orphans/stop", body);
|
|
2980
2979
|
}
|
|
2980
|
+
/**
|
|
2981
|
+
* @deprecated No KiCI server serves `/api/v1/api-keys`; use `createToken`
|
|
2982
|
+
* (`kici-admin token create`). Removed in v1.0.0.
|
|
2983
|
+
*/
|
|
2981
2984
|
async createApiKey(opts) {
|
|
2982
2985
|
return this.request("POST", "/api/v1/api-keys", opts);
|
|
2983
2986
|
}
|
|
2987
|
+
/**
|
|
2988
|
+
* @deprecated No KiCI server serves `/api/v1/api-keys`; use `createToken`
|
|
2989
|
+
* with `routingKey` (`kici-admin token create --routing-key`). Removed in v1.0.0.
|
|
2990
|
+
*/
|
|
2984
2991
|
async addRoutingKeyPermission(keyId, pattern) {
|
|
2985
2992
|
return this.request("POST", `/api/v1/api-keys/${encodeURIComponent(keyId)}/routing-permissions`, { pattern });
|
|
2986
2993
|
}
|
|
@@ -60,14 +60,15 @@ export interface TestTriggerInput {
|
|
|
60
60
|
/** Request trace ID from the HTTP request. */
|
|
61
61
|
requestId: string;
|
|
62
62
|
/**
|
|
63
|
-
* The principal that initiated this run
|
|
64
|
-
* `test.relay.trigger
|
|
63
|
+
* The principal that initiated this run: the one the Platform relays on
|
|
64
|
+
* `test.relay.trigger`, or the admin token's service account on the direct
|
|
65
|
+
* test-run routes.
|
|
65
66
|
*
|
|
66
|
-
* Required rather than optional: the relay handler
|
|
67
|
-
*
|
|
68
|
-
* optional field would let a future caller silently drop attribution
|
|
69
|
-
*
|
|
70
|
-
*
|
|
67
|
+
* Required rather than optional: the relay handler and the direct test-run
|
|
68
|
+
* routes are the production callers and both always pass an actor, and an
|
|
69
|
+
* optional field would let a future caller silently drop attribution, which
|
|
70
|
+
* leaves `execution_runs.triggered_by` NULL while the column claims to hold
|
|
71
|
+
* the initiator.
|
|
71
72
|
*/
|
|
72
73
|
actor: ActorPrincipal;
|
|
73
74
|
/** JSON-stringified lock file content for local repos with no remote. */
|
|
@@ -70,6 +70,11 @@ export declare enum UnroutableCause {
|
|
|
70
70
|
*/
|
|
71
71
|
OnlyOtherJobImageAgents = "only-other-job-image-agents"
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* The operator-facing reason a job is `unroutable`, naming the exact selectors
|
|
75
|
+
* that went unmatched. Regex matchers are rendered as their source so the
|
|
76
|
+
* message stays readable rather than printing `[object Object]`.
|
|
77
|
+
*/
|
|
73
78
|
export declare function unroutableMessage(job: JobRoutingFacts, cause?: UnroutableCause): string;
|
|
74
79
|
/**
|
|
75
80
|
* Split the two reasons a queued job never ran: nothing in the fleet matched
|
|
@@ -40,6 +40,8 @@ export interface AuthTokenInfo {
|
|
|
40
40
|
role: Role;
|
|
41
41
|
routingKey: string | null;
|
|
42
42
|
label: string;
|
|
43
|
+
/** The intended holder recorded at `token create --subject`, when one was. */
|
|
44
|
+
subject?: string | null;
|
|
43
45
|
}
|
|
44
46
|
/** The slice of TokenManager this middleware needs (keeps tests trivial to fake). */
|
|
45
47
|
export interface AuthTokenValidator {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Caller identity for orchestrator HTTP routes that act on behalf of the
|
|
3
|
+
* person or tool presenting a credential.
|
|
4
|
+
*
|
|
5
|
+
* Today the one credential is an admin token, resolved through the shared
|
|
6
|
+
* bearer-auth boundary (`resolveBearerAuth`), so the 401 / 503 semantics are
|
|
7
|
+
* identical to every admin route. The caller is a tagged union so a later
|
|
8
|
+
* credential kind (a signed command, for one) joins as another variant without
|
|
9
|
+
* touching the routes that consume it.
|
|
10
|
+
*/
|
|
11
|
+
import type { Context } from 'hono';
|
|
12
|
+
import { type ActorPrincipal } from '@kici-dev/engine';
|
|
13
|
+
import { type BearerAuthDeps } from './admin-auth.js';
|
|
14
|
+
import type { Role } from '../secrets/rbac.js';
|
|
15
|
+
/** A caller authenticated by an admin token. */
|
|
16
|
+
export interface TokenCaller {
|
|
17
|
+
kind: 'token';
|
|
18
|
+
tokenId: string;
|
|
19
|
+
label: string;
|
|
20
|
+
/** The intended holder recorded at `token create --subject`, or null. */
|
|
21
|
+
subject: string | null;
|
|
22
|
+
role: Role;
|
|
23
|
+
/** The single routing key a scoped token is restricted to, or null. */
|
|
24
|
+
routingKeyScope: string | null;
|
|
25
|
+
}
|
|
26
|
+
export type CallerOutcome = {
|
|
27
|
+
ok: true;
|
|
28
|
+
caller: TokenCaller;
|
|
29
|
+
} | {
|
|
30
|
+
ok: false;
|
|
31
|
+
status: 401 | 403 | 503;
|
|
32
|
+
error: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Resolve the request's caller.
|
|
36
|
+
*
|
|
37
|
+
* @param c - The request context (the `Authorization` header is read).
|
|
38
|
+
* @param deps - The token validator and log scope, as for `resolveBearerAuth`.
|
|
39
|
+
* @param opts.requireUnscoped - Refuse a routing-key-scoped token with 403.
|
|
40
|
+
* Routes whose routing key the server chooses set it: a scoped token has no
|
|
41
|
+
* key of its own to compare there, so accepting it would widen its reach.
|
|
42
|
+
* @returns The caller, or the status and body to answer with.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveCaller(c: Context<any>, deps: BearerAuthDeps, opts: {
|
|
45
|
+
requireUnscoped: boolean;
|
|
46
|
+
}): Promise<CallerOutcome>;
|
|
47
|
+
/**
|
|
48
|
+
* The principal a caller's actions are attributed to: a `service_account`
|
|
49
|
+
* bearing the admin token id, the same shape the admin held-run routes use.
|
|
50
|
+
*/
|
|
51
|
+
export declare function callerActor(caller: TokenCaller): ActorPrincipal;
|
|
52
|
+
//# sourceMappingURL=caller-identity.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import { OrchestratorMode } from '@kici-dev/engine';
|
|
3
|
+
import type { Database } from '../db/types.js';
|
|
4
|
+
import type { RbacEnforcer } from '../secrets/rbac.js';
|
|
5
|
+
import { type TestRelayHandlerDeps } from '../ws/test-relay-handlers.js';
|
|
6
|
+
import type { AuthTokenValidator } from './admin-auth.js';
|
|
7
|
+
import { type TokenCaller } from './caller-identity.js';
|
|
8
|
+
type TestDirectEnv = {
|
|
9
|
+
Variables: {
|
|
10
|
+
caller: TokenCaller;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
/** Answer for a Platform-connected orchestrator that has no org yet. */
|
|
14
|
+
export declare const NO_PLATFORM_ORG_MESSAGE = "This orchestrator has not received its organization from the KiCI Platform yet, so it cannot choose where to run the test. Retry when the orchestrator is connected.";
|
|
15
|
+
export interface TestDirectRouteDeps {
|
|
16
|
+
tokenManager: AuthTokenValidator;
|
|
17
|
+
rbac: RbacEnforcer;
|
|
18
|
+
mode: OrchestratorMode;
|
|
19
|
+
/** The org a connected orchestrator learned from the Platform; read per request. */
|
|
20
|
+
platformOrgId: () => string | null | undefined;
|
|
21
|
+
db: Kysely<Database>;
|
|
22
|
+
/** Builds the relay handlers' deps for one request (minus org, routing key and source). */
|
|
23
|
+
relayDeps: () => Omit<TestRelayHandlerDeps, 'orgId' | 'routingKey' | 'accessLogSource'>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The org a direct test run belongs to: the default org on an independent
|
|
27
|
+
* orchestrator, the Platform-assigned org otherwise (null until it is known).
|
|
28
|
+
*/
|
|
29
|
+
export declare function directOrgId(mode: OrchestratorMode, platformOrgId: string | null | undefined): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Build the route deps, or null when admin auth is not configured: without a
|
|
32
|
+
* token store there is no credential to authenticate a developer with.
|
|
33
|
+
*/
|
|
34
|
+
export declare function testDirectRouteDeps(input: {
|
|
35
|
+
adminDeps?: {
|
|
36
|
+
tokenManager: AuthTokenValidator;
|
|
37
|
+
rbac: RbacEnforcer;
|
|
38
|
+
};
|
|
39
|
+
}, rest: Omit<TestDirectRouteDeps, 'tokenManager' | 'rbac'>): TestDirectRouteDeps | null;
|
|
40
|
+
/**
|
|
41
|
+
* Build the direct test-run router: the routes under `/api/v1/test`, each
|
|
42
|
+
* behind admin-token authentication that refuses a routing-key-scoped token.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createTestDirectRoutes(deps: TestDirectRouteDeps): import("hono").Hono<TestDirectEnv, import("hono/types").BlankSchema, "/">;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=test-direct.d.ts.map
|
package/dist/routes/uploads.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Mints an upload record and a presigned PUT URL + ephemeral X25519 public key
|
|
5
5
|
* for the overlay tarball. The developer encrypts the tarball with the returned
|
|
6
6
|
* public key and PUTs it directly to the object store; a test trigger then
|
|
7
|
-
* references the upload id.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* references the upload id. It is invoked by the `test.relay.uploads.init`
|
|
8
|
+
* relay handler (a run routed through the Platform) and by the direct
|
|
9
|
+
* test-run routes (`POST /api/v1/test/uploads/init`).
|
|
10
10
|
*/
|
|
11
11
|
import type { Kysely } from 'kysely';
|
|
12
12
|
import type { Database } from '../db/types.js';
|
|
@@ -19,12 +19,13 @@ export interface InitTestUploadParams {
|
|
|
19
19
|
compressedSize?: number;
|
|
20
20
|
/** PAT/actor identity that owns this upload, written to `test_uploads.created_by`. */
|
|
21
21
|
createdBy?: string | null;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The orchestrator has no object storage, so it cannot mint an upload URL.
|
|
25
|
+
* Callers answer it as "service unavailable" with the message as-is.
|
|
26
|
+
*/
|
|
27
|
+
export declare class TestUploadStorageUnavailableError extends Error {
|
|
28
|
+
constructor(message: string);
|
|
28
29
|
}
|
|
29
30
|
/** Result of {@link initTestUpload}. */
|
|
30
31
|
export interface InitTestUploadResult {
|
|
@@ -41,8 +42,8 @@ export interface InitTestUploadDeps {
|
|
|
41
42
|
/**
|
|
42
43
|
* Mint an upload record and return a presigned PUT URL + ephemeral X25519
|
|
43
44
|
* public key. The encryption keypair is generated per upload; the private key
|
|
44
|
-
* is stored orchestrator-side for post-PUT decryption. The
|
|
45
|
-
*
|
|
45
|
+
* is stored orchestrator-side for post-PUT decryption. The URL is the
|
|
46
|
+
* developer-facing one (`CacheStorage.getInternalUploadUrl`).
|
|
46
47
|
*/
|
|
47
48
|
export declare function initTestUpload(deps: InitTestUploadDeps, params: InitTestUploadParams): Promise<InitTestUploadResult>;
|
|
48
49
|
//# sourceMappingURL=uploads.d.ts.map
|
package/dist/secrets/rbac.d.ts
CHANGED
|
@@ -23,7 +23,11 @@ export type Permission = 'context.create' | 'context.read' | 'context.update' |
|
|
|
23
23
|
/** Stop live Firecracker VMs the node's orchestrator does not track. */
|
|
24
24
|
| 'scaler.manage'
|
|
25
25
|
/** Drop a departed peer from the coordinators' live peer registries. */
|
|
26
|
-
| 'peer.manage'
|
|
26
|
+
| 'peer.manage'
|
|
27
|
+
/** Start or cancel a `kici run remote` test run through the direct test-run routes. */
|
|
28
|
+
| 'test_run.trigger'
|
|
29
|
+
/** Follow a test run's status and logs through the direct test-run routes. */
|
|
30
|
+
| 'test_run.read';
|
|
27
31
|
/**
|
|
28
32
|
* Error thrown when a role lacks the required permission.
|
|
29
33
|
*/
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* they use `requireUnscopedToken` instead.
|
|
26
26
|
*/
|
|
27
27
|
import type { Context } from 'hono';
|
|
28
|
+
export declare const UNSCOPED_REQUIRED_MESSAGE = "Access denied: this route requires an unscoped admin token (the calling token is restricted to a single routing key)";
|
|
28
29
|
/**
|
|
29
30
|
* Reject the request with 403 when the calling token has a routing-key
|
|
30
31
|
* scope and the request targets a different routing key.
|