@kynver-app/runtime 0.1.166 → 0.1.171

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.
@@ -15,5 +15,5 @@ export declare function normalizeWorkerPoolBoxKind(raw: string | null | undefine
15
15
  * Never maps AgentOS workspace slug alone to box kind — Forge installs must set
16
16
  * `boxKind` in ~/.kynver/config.json or `KYNVER_BOX_KIND`.
17
17
  */
18
- export declare function resolveBoxIdentity(env?: NodeJS.ProcessEnv, config?: Pick<KynverUserConfig, "boxKind">): ResolvedBoxIdentity;
19
- export declare function resolveBoxKindFromConfig(config?: Pick<KynverUserConfig, "boxKind">, env?: NodeJS.ProcessEnv): WorkerPoolBoxKind;
18
+ export declare function resolveBoxIdentity(env?: NodeJS.ProcessEnv, config?: Pick<KynverUserConfig, "boxKind" | "boxId">): ResolvedBoxIdentity;
19
+ export declare function resolveBoxKindFromConfig(config?: Pick<KynverUserConfig, "boxKind" | "boxId">, env?: NodeJS.ProcessEnv): WorkerPoolBoxKind;
@@ -1,4 +1,13 @@
1
+ import type { KynverUserConfig } from "./config.js";
1
2
  export { normalizeWorkerPoolBoxKind, resolveBoxIdentity } from "./box-identity.js";
2
3
  /** @deprecated Prefer resolveBoxIdentity — kept for callers that only need the kind string. */
3
4
  export declare function resolveBoxKindFromEnv(env?: NodeJS.ProcessEnv): string;
4
5
  export declare function defaultBoxId(boxKind: string, hostLabel?: string | null): string;
6
+ export declare function normalizeConfiguredBoxId(raw: string, boxKind: string): string;
7
+ export declare function resolveConfiguredBoxId(input: {
8
+ boxKind: string;
9
+ hostLabel?: string | null;
10
+ explicitBoxId?: string | null;
11
+ config?: Pick<KynverUserConfig, "boxId"> | null;
12
+ env?: NodeJS.ProcessEnv;
13
+ }): string;
@@ -22,6 +22,12 @@ export type GoldenPathCheckCode =
22
22
  | "missing_codex_auth"
23
23
  /** Job's agentOsId does not match the runner's configured workspace. */
24
24
  | "wrong_workspace"
25
+ /**
26
+ * Job envelope is structurally invalid (missing/blank required field or
27
+ * malformed dates). Indicates a control-plane/serialization problem, not a
28
+ * runner-config problem — distinct from `wrong_workspace`.
29
+ */
30
+ | "malformed_envelope"
25
31
  /** Job envelope has expired (expiresAt in the past). */
26
32
  | "job_expired"
27
33
  /**
@@ -24,6 +24,7 @@ export declare function executeCommandTurn(target: ChatBridgeTarget, turn: {
24
24
  turnId: string;
25
25
  payload: {
26
26
  argv?: unknown;
27
+ authProof?: unknown;
27
28
  };
28
29
  }): Promise<void>;
29
30
  /** Execute one claimed turn and stream its events back. Never throws. */
@@ -0,0 +1,57 @@
1
+ /** Default proof lifetime — must cover one gateway command wait + relay latency. */
2
+ export declare const COMMAND_AUTH_PROOF_TTL_SEC = 120;
3
+ export interface CommandAuthorizationProofPayload {
4
+ v: 1;
5
+ agentOsId: string;
6
+ argv: string[];
7
+ userId: string;
8
+ /** Unix epoch seconds. */
9
+ exp: number;
10
+ /** Single-use replay guard (base64url). */
11
+ nonce: string;
12
+ }
13
+ export interface SignedCommandAuthorizationProof {
14
+ payload: CommandAuthorizationProofPayload;
15
+ /** base64url Ed25519 signature over `canonicalJsonStringify(payload)`. */
16
+ signature: string;
17
+ /** Identifies the signing key (`ca-<sha256(publicKey) prefix>`). */
18
+ publicKeyId: string;
19
+ }
20
+ export type CommandAuthProofVerifyResult = {
21
+ ok: true;
22
+ payload: CommandAuthorizationProofPayload;
23
+ } | {
24
+ ok: false;
25
+ reason: string;
26
+ };
27
+ export interface CommandAuthSigningKey {
28
+ seed: Uint8Array;
29
+ rawPublicKey: Uint8Array;
30
+ publicKeyId: string;
31
+ usingDevFallbackKey: boolean;
32
+ }
33
+ /**
34
+ * Committed DEV fallback public key (`ca-6297fb8e1773`). The matching private
35
+ * seed is committed below — NOT a production trust root.
36
+ */
37
+ export declare const PINNED_COMMAND_AUTH_PUBLIC_KEYS: Readonly<Record<string, string>>;
38
+ export declare function deriveCommandAuthKeyId(rawPublicKey: Uint8Array): string;
39
+ export declare function resolveCommandAuthPublicKey(publicKeyId: string, env?: Record<string, string | undefined>): Uint8Array | null;
40
+ export declare function argvMatchesProof(proofArgv: unknown, expectedArgv: readonly string[]): boolean;
41
+ export declare function isSignedCommandAuthProofShape(value: unknown): value is SignedCommandAuthorizationProof;
42
+ /** Verify signature + expiry + workspace/argv binding. */
43
+ export declare function verifyCommandAuthorizationProof(signed: unknown, expected: {
44
+ agentOsId: string;
45
+ argv: readonly string[];
46
+ }, env?: Record<string, string | undefined>, nowSec?: number): CommandAuthProofVerifyResult;
47
+ export declare function resolveCommandAuthSigningKey(env?: Record<string, string | undefined>): CommandAuthSigningKey;
48
+ /** Mint a signed proof after the app-side approval gate passes. */
49
+ export declare function issueCommandAuthorizationProof(args: {
50
+ agentOsId: string;
51
+ argv: readonly string[];
52
+ userId: string;
53
+ ttlSec?: number;
54
+ nowSec?: number;
55
+ env?: Record<string, string | undefined>;
56
+ }): SignedCommandAuthorizationProof;
57
+ export declare function commandAuthProofKeyFingerprint(key: CommandAuthSigningKey): string;
@@ -0,0 +1 @@
1
+ import{createHash as c,createPrivateKey as d,createPublicKey as l,randomBytes as p,sign as m,verify as h}from"node:crypto";function f(e){return JSON.stringify(u(e))}function u(e){if(Array.isArray(e))return e.map(u);if(e&&typeof e=="object"){let r={};for(let n of Object.keys(e).sort())r[n]=u(e[n]);return r}return e}function o(e){if(!e)return null;let r=e.trim();if(!r)return null;if(/^[0-9a-fA-F]{64}$/.test(r))return new Uint8Array(r.match(/.{2}/g).map(n=>parseInt(n,16)));try{let n=Buffer.from(r,"base64");if(n.length===32)return new Uint8Array(n)}catch{}return null}var b=120,A=Buffer.from("302a300506032b6570032100","hex"),g=Buffer.from("302e020100300506032b657004220420","hex"),I="c0021e9312b0a479dbd2eb8dec0deedbe0dd6445eff431e372fa49fa21d42ffa",P={"ca-6297fb8e1773":"16ae5cb2a61f8c94cf1b86e8258f9c2f2ff6aba5e6136250a422209b6e866881"};function y(e){return`ca-${c("sha256").update(Buffer.from(e)).digest("hex").slice(0,12)}`}function K(e,r=process.env){let n=o(r.KYNVER_COMMAND_AUTH_PUBLIC_KEY);if(n)return y(n)!==e?null:n;if(r.NODE_ENV==="production")return null;let t=P[e];return t?o(t):null}function B(e){return l({key:Buffer.concat([A,Buffer.from(e)]),format:"der",type:"spki"})}function x(e,r){return!Array.isArray(e)||e.length!==r.length?!1:e.every((n,t)=>typeof n=="string"&&n===r[t])}function C(e){if(!e||typeof e!="object")return!1;let r=e;if(typeof r.signature!="string"||!r.signature||typeof r.publicKeyId!="string"||!r.publicKeyId)return!1;let n=r.payload;return!(!n||typeof n!="object"||n.v!==1||typeof n.agentOsId!="string"||!n.agentOsId||!Array.isArray(n.argv)||n.argv.some(t=>typeof t!="string")||typeof n.userId!="string"||!n.userId||typeof n.exp!="number"||!Number.isFinite(n.exp)||typeof n.nonce!="string"||!n.nonce)}function O(e,r,n=process.env,t=Math.floor(Date.now()/1e3)){if(!C(e))return{ok:!1,reason:"malformed command authorization proof"};if(e.payload.agentOsId!==r.agentOsId)return{ok:!1,reason:"agentOsId mismatch"};if(!x(e.payload.argv,r.argv))return{ok:!1,reason:"argv mismatch"};if(e.payload.exp<=t)return{ok:!1,reason:"proof expired"};let i=K(e.publicKeyId,n);if(!i)return{ok:!1,reason:`no verification key for publicKeyId "${e.publicKeyId}"`};let a;try{a=Buffer.from(e.signature,"base64url")}catch{return{ok:!1,reason:"signature is not base64url"}}if(a.length!==64)return{ok:!1,reason:"signature is not a 64-byte Ed25519 signature"};try{let s=Buffer.from(f(e.payload),"utf8");return h(null,s,B(i),a)?{ok:!0,payload:e.payload}:{ok:!1,reason:"Ed25519 signature mismatch"}}catch(s){return{ok:!1,reason:`signature verification failed: ${s.message}`}}}function k(e){let r=d({key:Buffer.concat([g,Buffer.from(e)]),format:"der",type:"pkcs8"}),n=l(r).export({format:"der",type:"spki"});return new Uint8Array(n.subarray(n.length-32))}function v(e=process.env){let r=o(e.KYNVER_COMMAND_AUTH_KEY);if(!r&&e.NODE_ENV==="production")throw new Error("KYNVER_COMMAND_AUTH_KEY must be set in production; refusing to sign command proofs with the committed dev key.");let n=r??o(I),t=k(n);return{seed:n,rawPublicKey:t,publicKeyId:y(t),usingDevFallbackKey:!r}}function S(e,r){let n=d({key:Buffer.concat([g,Buffer.from(r.seed)]),format:"der",type:"pkcs8"}),t=Buffer.from(f(e),"utf8");return{payload:e,signature:m(null,t,n).toString("base64url"),publicKeyId:r.publicKeyId}}function U(e){let r=e.env??process.env,n=e.nowSec??Math.floor(Date.now()/1e3),t=e.ttlSec??b,i={v:1,agentOsId:e.agentOsId,argv:[...e.argv],userId:e.userId,exp:n+t,nonce:p(16).toString("base64url")};return S(i,v(r))}function D(e){return c("sha256").update(Buffer.from(e.rawPublicKey)).digest("hex").slice(0,16)}export{b as COMMAND_AUTH_PROOF_TTL_SEC,P as PINNED_COMMAND_AUTH_PUBLIC_KEYS,x as argvMatchesProof,D as commandAuthProofKeyFingerprint,y as deriveCommandAuthKeyId,C as isSignedCommandAuthProofShape,U as issueCommandAuthorizationProof,K as resolveCommandAuthPublicKey,v as resolveCommandAuthSigningKey,O as verifyCommandAuthorizationProof};
@@ -1,8 +1,10 @@
1
+ import { type SignedCommandAuthorizationProof } from "./command-auth-proof.js";
1
2
  export interface CommandTurnResult {
2
3
  exitCode: number | null;
3
4
  timedOut: boolean;
4
5
  refused?: string;
5
6
  }
7
+ export declare function verifyCommandTurnAuthorization(agentOsId: string, argv: readonly string[], authProof: unknown, env?: Record<string, string | undefined>): string | null;
6
8
  /**
7
9
  * Execute one command turn. `pushDelta` receives batched output text;
8
10
  * resolves with the terminal result (never throws).
@@ -10,4 +12,7 @@ export interface CommandTurnResult {
10
12
  export declare function executeLocalCommand(argv: string[], pushDelta: (text: string) => void, opts?: {
11
13
  cliEntry?: string;
12
14
  timeoutMs?: number;
15
+ agentOsId?: string;
16
+ authProof?: SignedCommandAuthorizationProof | unknown;
17
+ env?: Record<string, string | undefined>;
13
18
  }): Promise<CommandTurnResult>;