cyrus-config-updater 0.2.73 → 0.2.75

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.
@@ -37,31 +37,18 @@ export declare function ensureGitHubCredentialHelper(cyrusHome: string): string;
37
37
  * provisioned from older images keep their baked wrapper until rebuilt;
38
38
  * since the wrapper lives in the cyrus user's home, rewrite it here on
39
39
  * token pushes — making per-org gh independent of the image rollout.
40
- * No-op when no wrapper exists (self-host), it already execs the
41
- * resolver, or it has an unrecognized shape.
40
+ * No-op when no wrapper exists (self-host), it already has the managed
41
+ * fence, or it has an unrecognized shape.
42
42
  */
43
43
  export declare function ensureGhWrapperSupportsCyrusToken(homeDir?: string): boolean;
44
- /**
45
- * Authenticate the `gh` CLI with a pushed installation token.
46
- *
47
- * The droplet-local token refresh service used to run `gh auth login` every
48
- * 20 minutes; with refresh moved to cyrus-hosted, this keeps bare `gh`
49
- * usage (outside sessions, and sessions on droplet images whose gh wrapper
50
- * strips GH_TOKEN) authenticated. Multi-org correctness comes from the
51
- * per-session GH_TOKEN env var; this default uses the first token, which is
52
- * exact for single-installation teams. Refreshed on every token push.
53
- *
54
- * Non-fatal by design — self-host machines may not have `gh` installed.
55
- */
56
- export declare function configureGhCliAuth(token: string): void;
57
44
  /**
58
45
  * Handle a GitHub installation tokens push from cyrus-hosted.
59
46
  *
60
47
  * Persists the per-installation tokens to `<cyrusHome>/github-tokens.json`
61
48
  * (atomically, mode 0600), ensures the git credential helper is installed
62
49
  * so concurrent git operations against different GitHub orgs each
63
- * authenticate with the right token, and refreshes the `gh` CLI's stored
64
- * auth with the first pushed token.
50
+ * authenticate with the right token. gh uses per-invocation resolution; no
51
+ * installation token is persisted into native gh hosts/keyring storage.
65
52
  *
66
53
  * @param rawPayload - Unvalidated payload from the request
67
54
  * @param cyrusHome - Path to the Cyrus home directory
@@ -1 +1 @@
1
- {"version":3,"file":"githubTokens.d.ts","sourceRoot":"","sources":["../../src/handlers/githubTokens.ts"],"names":[],"mappings":"AAaA,OAAO,EACN,KAAK,WAAW,EAGhB,MAAM,aAAa,CAAC;AAUrB;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAO/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA6BtE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iCAAiC,CAChD,OAAO,GAAE,MAAkB,GACzB,OAAO,CA2BT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACvC,UAAU,EAAE,OAAO,EACnB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CAqFtB"}
1
+ {"version":3,"file":"githubTokens.d.ts","sourceRoot":"","sources":["../../src/handlers/githubTokens.ts"],"names":[],"mappings":"AAaA,OAAO,EACN,KAAK,WAAW,EAGhB,MAAM,aAAa,CAAC;AAqBrB;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA8BtE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iCAAiC,CAChD,OAAO,GAAE,MAAkB,GACzB,OAAO,CA8BT;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACvC,UAAU,EAAE,OAAO,EACnB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CAyDtB"}
@@ -12,6 +12,13 @@ function bundledScriptPath(scriptName) {
12
12
  const here = dirname(fileURLToPath(import.meta.url));
13
13
  return join(here, "..", "..", "scripts", scriptName);
14
14
  }
15
+ /** Install shared policy before either consumer; retain enrollment on deletion. */
16
+ function ensureManagedAuthPolicy(cyrusHome) {
17
+ const scripts = join(cyrusHome, "scripts");
18
+ mkdirSync(scripts, { recursive: true });
19
+ writeFileSync(join(cyrusHome, "github-auth-managed"), "1\n", { mode: 0o600 });
20
+ copyFileSync(bundledScriptPath("managed-github-auth.cjs"), join(scripts, "managed-github-auth.cjs"));
21
+ }
15
22
  /**
16
23
  * Install the per-invocation gh token resolver to
17
24
  * `<cyrusHome>/scripts/gh-cyrus.cjs`. The droplet's `~/.local/bin/gh`
@@ -21,6 +28,7 @@ function bundledScriptPath(scriptName) {
21
28
  * GitHub orgs. Idempotent.
22
29
  */
23
30
  export function ensureGhTokenResolver(cyrusHome) {
31
+ ensureManagedAuthPolicy(cyrusHome);
24
32
  const scriptDir = join(cyrusHome, "scripts");
25
33
  const scriptDest = join(scriptDir, "gh-cyrus.cjs");
26
34
  mkdirSync(scriptDir, { recursive: true });
@@ -45,6 +53,7 @@ export function ensureGhTokenResolver(cyrusHome) {
45
53
  * Returns the absolute path of the installed helper script.
46
54
  */
47
55
  export function ensureGitHubCredentialHelper(cyrusHome) {
56
+ ensureManagedAuthPolicy(cyrusHome);
48
57
  const scriptDir = join(cyrusHome, "scripts");
49
58
  const scriptDest = join(scriptDir, "git-credential-cyrus.cjs");
50
59
  mkdirSync(scriptDir, { recursive: true });
@@ -82,8 +91,8 @@ export function ensureGitHubCredentialHelper(cyrusHome) {
82
91
  * provisioned from older images keep their baked wrapper until rebuilt;
83
92
  * since the wrapper lives in the cyrus user's home, rewrite it here on
84
93
  * token pushes — making per-org gh independent of the image rollout.
85
- * No-op when no wrapper exists (self-host), it already execs the
86
- * resolver, or it has an unrecognized shape.
94
+ * No-op when no wrapper exists (self-host), it already has the managed
95
+ * fence, or it has an unrecognized shape.
87
96
  */
88
97
  export function ensureGhWrapperSupportsCyrusToken(homeDir = homedir()) {
89
98
  const wrapperPath = join(homeDir, ".local", "bin", "gh");
@@ -92,52 +101,35 @@ export function ensureGhWrapperSupportsCyrusToken(homeDir = homedir()) {
92
101
  const current = readFileSync(wrapperPath, "utf8");
93
102
  // Only rewrite the known droplet wrapper shapes (the original
94
103
  // strip-everything wrapper and the interim CYRUS_GH_TOKEN one), and
95
- // only when they predate the resolver.
96
- if (current.includes("gh-cyrus.cjs") || !current.includes("/usr/bin/gh")) {
104
+ // upgrade the first-generation resolver wrapper too.
105
+ if (current.includes("Cyrus managed auth v2") ||
106
+ !current.includes("/usr/bin/gh")) {
97
107
  return false;
98
108
  }
99
109
  const updated = `#!/usr/bin/env bash
100
- # Cyrus-managed gh wrapper. The resolver picks the GitHub App installation
101
- # token for the org each command targets (multi-org support); without it,
102
- # strip injected tokens so gh falls back to its own stored auth.
103
- RESOLVER="$HOME/.cyrus/scripts/gh-cyrus.cjs"
110
+ # Cyrus managed auth v2: no cached-auth fallback if the resolver is unavailable.
111
+ CYRUS_AUTH_HOME="\${CYRUS_HOME:-$HOME/.cyrus}"
112
+ RESOLVER="$CYRUS_AUTH_HOME/scripts/gh-cyrus.cjs"
104
113
  if [ -f "$RESOLVER" ]; then
105
114
  exec node "$RESOLVER" "$@"
106
115
  fi
107
- if [ -n "\${CYRUS_GH_TOKEN:-}" ]; then
108
- exec env -u GITHUB_TOKEN GH_TOKEN="$CYRUS_GH_TOKEN" /usr/bin/gh "$@"
116
+ if [ -e "$CYRUS_AUTH_HOME/github-tokens.json" ] || [ -e "$CYRUS_AUTH_HOME/github-auth-managed" ]; then
117
+ echo "gh-cyrus: managed credential resolver unavailable" >&2
118
+ exit 1
109
119
  fi
110
- exec env -u GITHUB_TOKEN -u GH_TOKEN /usr/bin/gh "$@"
120
+ exec /usr/bin/gh "$@"
111
121
  `;
112
122
  writeFileSync(wrapperPath, updated, { mode: 0o755 });
113
123
  return true;
114
124
  }
115
- /**
116
- * Authenticate the `gh` CLI with a pushed installation token.
117
- *
118
- * The droplet-local token refresh service used to run `gh auth login` every
119
- * 20 minutes; with refresh moved to cyrus-hosted, this keeps bare `gh`
120
- * usage (outside sessions, and sessions on droplet images whose gh wrapper
121
- * strips GH_TOKEN) authenticated. Multi-org correctness comes from the
122
- * per-session GH_TOKEN env var; this default uses the first token, which is
123
- * exact for single-installation teams. Refreshed on every token push.
124
- *
125
- * Non-fatal by design — self-host machines may not have `gh` installed.
126
- */
127
- export function configureGhCliAuth(token) {
128
- execFileSync("gh", ["auth", "login", "--with-token"], {
129
- input: token,
130
- stdio: ["pipe", "ignore", "ignore"],
131
- });
132
- }
133
125
  /**
134
126
  * Handle a GitHub installation tokens push from cyrus-hosted.
135
127
  *
136
128
  * Persists the per-installation tokens to `<cyrusHome>/github-tokens.json`
137
129
  * (atomically, mode 0600), ensures the git credential helper is installed
138
130
  * so concurrent git operations against different GitHub orgs each
139
- * authenticate with the right token, and refreshes the `gh` CLI's stored
140
- * auth with the first pushed token.
131
+ * authenticate with the right token. gh uses per-invocation resolution; no
132
+ * installation token is persisted into native gh hosts/keyring storage.
141
133
  *
142
134
  * @param rawPayload - Unvalidated payload from the request
143
135
  * @param cyrusHome - Path to the Cyrus home directory
@@ -179,41 +171,22 @@ export async function handleGitHubTokens(rawPayload, cyrusHome) {
179
171
  }
180
172
  try {
181
173
  ensureGhTokenResolver(cyrusHome);
182
- }
183
- catch (error) {
184
- // Non-fatal: gh falls back to CYRUS_GH_TOKEN / hosts.yml auth.
185
- console.warn("[githubTokens] gh token resolver install failed:", error instanceof Error ? error.message : String(error));
186
- }
187
- try {
188
- // cyrusHome is <home>/.cyrus on droplets, so the wrapper lives at
189
- // <parent of cyrusHome>/.local/bin/gh. Using the parent (rather than
190
- // os.homedir()) keeps this no-op for custom cyrus-home layouts and
191
- // hermetic in tests.
192
174
  ensureGhWrapperSupportsCyrusToken(dirname(cyrusHome));
193
175
  }
194
- catch (error) {
195
- // Non-fatal: the wrapper rewrite is a droplet-only nicety.
196
- console.warn("[githubTokens] gh wrapper self-heal failed:", error instanceof Error ? error.message : String(error));
197
- }
198
- let ghAuthConfigured = false;
199
- const firstToken = payload.tokens[0]?.token;
200
- if (firstToken) {
201
- try {
202
- configureGhCliAuth(firstToken);
203
- ghAuthConfigured = true;
204
- }
205
- catch (error) {
206
- // Non-fatal: gh may not be installed (self-host), and git auth via
207
- // the credential helper is unaffected.
208
- console.warn("[githubTokens] gh CLI auth refresh failed:", error instanceof Error ? error.message : String(error));
209
- }
176
+ catch {
177
+ // Delivery is not complete when the authentication fence cannot be installed.
178
+ return {
179
+ success: false,
180
+ error: "Failed to configure managed gh authentication",
181
+ };
210
182
  }
211
183
  return {
212
184
  success: true,
213
185
  message: "GitHub installation tokens updated successfully",
214
186
  data: {
215
187
  tokensCount: payload.tokens.length,
216
- ghAuthConfigured,
188
+ ghAuthConfigured: false,
189
+ ghResolverInstalled: true,
217
190
  },
218
191
  };
219
192
  }
@@ -1 +1 @@
1
- {"version":3,"file":"githubTokens.js","sourceRoot":"","sources":["../../src/handlers/githubTokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"githubTokens.js","sourceRoot":"","sources":["../../src/handlers/githubTokens.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -37,6 +37,11 @@ export declare const CyrusConfigPayloadSchema: z.ZodObject<{
37
37
  claudeDefaultFallbackModel: z.ZodOptional<z.ZodString>;
38
38
  geminiDefaultModel: z.ZodOptional<z.ZodString>;
39
39
  codexDefaultModel: z.ZodOptional<z.ZodString>;
40
+ codexSandboxMode: z.ZodOptional<z.ZodEnum<{
41
+ "danger-full-access": "danger-full-access";
42
+ "read-only": "read-only";
43
+ "workspace-write": "workspace-write";
44
+ }>>;
40
45
  cursorDefaultModel: z.ZodOptional<z.ZodString>;
41
46
  cursorDefaultFallbackModel: z.ZodOptional<z.ZodString>;
42
47
  opencodeDefaultModel: z.ZodOptional<z.ZodString>;
@@ -132,6 +137,7 @@ export declare const CyrusConfigPayloadSchema: z.ZodObject<{
132
137
  }, z.core.$strip>>;
133
138
  }, z.core.$strip>>;
134
139
  systemWideCert: z.ZodOptional<z.ZodBoolean>;
140
+ writablePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
135
141
  logRequests: z.ZodOptional<z.ZodBoolean>;
136
142
  }, z.core.$strip>>;
137
143
  repositories: z.ZodArray<z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACvC,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CACrE;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,aAAa,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAC7D,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IACxD,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;CACvD;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;iBAcpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;CACX;AAED,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,aAAa,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,uHAAuH;IACvH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyrus-config-updater",
3
- "version": "0.2.73",
3
+ "version": "0.2.75",
4
4
  "description": "Configuration update handlers for Cyrus agent",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,15 +21,15 @@
21
21
  "scripts"
22
22
  ],
23
23
  "dependencies": {
24
- "@modelcontextprotocol/sdk": "^1.31.0",
25
- "fastify": "^5.12.5",
26
- "zod": "^4.3.6",
27
- "cyrus-core": "0.2.73"
24
+ "@modelcontextprotocol/sdk": "^1.32.1",
25
+ "fastify": "^5.12.7",
26
+ "zod": "^4.6.7",
27
+ "cyrus-core": "0.2.75"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "^20.12.7",
31
31
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
32
- "vitest": "^4.1.11"
32
+ "vitest": "^4.1.12"
33
33
  },
34
34
  "keywords": [
35
35
  "config",
@@ -14,24 +14,18 @@
14
14
  * 2. A positional repository for `repo view`, `clone`, or `fork`.
15
15
  * 3. GH_REPO, then the cwd's `remote.origin.url` (how gh infers "the current
16
16
  * repository").
17
- * Then the token, from `<cyrusHome>/github-tokens.json` (pushed by
18
- * cyrus-hosted):
19
- * 3. The org-matched token.
20
- * 4. `CYRUS_GH_TOKEN` from the session env (set to the session's primary
21
- * repository's org token — covers repo-less commands like `gh api`).
22
- * 5. The single valid token, when exactly one exists.
23
- * 6. No token: fall through to gh's own stored auth (hosts.yml).
24
- *
25
- * In every case the customer-controlled GITHUB_TOKEN / GH_TOKEN env vars
26
- * are removed from gh's environment (the wrapper's historical contract);
27
- * they remain untouched for every other tool in the session.
17
+ * A managed store is authoritative. Explicit owners require an org match;
18
+ * repo-less commands may use a still-current session hint or a single token.
19
+ * Missing/expired/removed credentials refuse before native gh can consult
20
+ * hosts.yml or a keyring. With no store/enrollment, unmanaged auth is untouched.
28
21
  */
29
22
  "use strict";
30
23
 
31
24
  const { spawnSync } = require("node:child_process");
32
- const fs = require("node:fs");
33
- const os = require("node:os");
34
- const path = require("node:path");
25
+ const {
26
+ loadManagedAuth,
27
+ resolveManagedToken,
28
+ } = require("./managed-github-auth.cjs");
35
29
 
36
30
  /** Extract the owner/org from common GitHub repo references. */
37
31
  function ownerFromRepoRef(ref) {
@@ -118,56 +112,71 @@ function ownerFromCwd() {
118
112
  return ownerFromRepoRef((result.stdout || "").trim());
119
113
  }
120
114
 
121
- /** Non-expired tokens from the Cyrus token store file. */
122
- function loadValidTokens() {
123
- const cyrusHome = process.env.CYRUS_HOME || path.join(os.homedir(), ".cyrus");
124
- const tokensFile = path.join(cyrusHome, "github-tokens.json");
125
- let tokens = [];
126
- try {
127
- const parsed = JSON.parse(fs.readFileSync(tokensFile, "utf8"));
128
- if (Array.isArray(parsed.tokens)) tokens = parsed.tokens;
129
- } catch {
130
- return [];
131
- }
132
- const now = Date.now();
133
- return tokens.filter((t) => {
134
- if (!t || typeof t.token !== "string" || t.token.length === 0) return false;
135
- const expiresAt = Date.parse(t.expiresAt);
136
- return !Number.isNaN(expiresAt) && expiresAt > now;
137
- });
138
- }
139
-
140
- function resolveToken(args) {
141
- const owner =
142
- ownerFromArgs(args) ||
143
- ownerFromRepoRef(process.env.GH_REPO) ||
144
- ownerFromCwd();
145
- const valid = loadValidTokens();
146
-
147
- if (owner) {
148
- const lowered = owner.toLowerCase();
149
- const match = valid.find(
150
- (t) =>
151
- typeof t.organization === "string" &&
152
- t.organization.toLowerCase() === lowered,
115
+ /** Explicit REST repo/org targets override cwd and session hints. */
116
+ function ownerFromApi(args, repositoryOwner) {
117
+ if (args[0] !== "api") return "";
118
+ const valueFlags = new Set([
119
+ "--method",
120
+ "-X",
121
+ "--header",
122
+ "-H",
123
+ "--field",
124
+ "-F",
125
+ "--raw-field",
126
+ "-f",
127
+ "--hostname",
128
+ "--input",
129
+ "--jq",
130
+ "-q",
131
+ "--template",
132
+ "-t",
133
+ "--cache",
134
+ ]);
135
+ for (let i = 1; i < args.length; i++) {
136
+ if (valueFlags.has(args[i])) {
137
+ i++;
138
+ continue;
139
+ }
140
+ if (args[i].startsWith("-")) continue;
141
+ const match = args[i].match(
142
+ /^(?:https:\/\/api\.github\.com)?\/?(?:repos|orgs)\/([^/?#]+)/i,
153
143
  );
154
- if (match) return match.token;
144
+ if (!match) return "";
145
+ // gh expands {owner} using its repository context. Keep an unresolved
146
+ // placeholder explicit so it cannot fall back to the single/session token.
147
+ return repositoryOwner
148
+ ? match[1].replaceAll("{owner}", repositoryOwner)
149
+ : match[1];
155
150
  }
156
- if (process.env.CYRUS_GH_TOKEN) return process.env.CYRUS_GH_TOKEN;
157
- if (valid.length === 1) return valid[0].token;
158
- return undefined;
151
+ return "";
159
152
  }
160
153
 
161
154
  function main() {
162
155
  const args = process.argv.slice(2);
163
156
 
164
- // Strip the customer-controlled token vars from gh's env (historical
165
- // wrapper contract); set GH_TOKEN only when Cyrus resolved a token.
166
157
  const env = { ...process.env };
167
- delete env.GITHUB_TOKEN;
168
- delete env.GH_TOKEN;
169
- const token = resolveToken(args);
170
- if (token) env.GH_TOKEN = token;
158
+ const auth = loadManagedAuth();
159
+ if (auth.managed && args.length === 1 && args[0] === "--version") {
160
+ // The health handler probes installation separately from authentication.
161
+ // Native gh --version does not contact GitHub or inspect stored auth.
162
+ delete env.GITHUB_TOKEN;
163
+ delete env.GH_TOKEN;
164
+ delete env.CYRUS_GH_TOKEN;
165
+ } else if (auth.managed) {
166
+ const repositoryOwner =
167
+ ownerFromArgs(args) || ownerFromRepoRef(env.GH_REPO) || ownerFromCwd();
168
+ const owner = ownerFromApi(args, repositoryOwner) || repositoryOwner;
169
+ const token = resolveManagedToken(auth.tokens, owner, env.CYRUS_GH_TOKEN);
170
+ if (!token) {
171
+ console.error(
172
+ "gh-cyrus: no current managed GitHub credential for this command",
173
+ );
174
+ process.exit(1);
175
+ }
176
+ delete env.GITHUB_TOKEN;
177
+ delete env.CYRUS_GH_TOKEN;
178
+ env.GH_TOKEN = token;
179
+ }
171
180
 
172
181
  const ghBin = process.env.CYRUS_GH_REAL_BIN || "/usr/bin/gh";
173
182
  const result = spawnSync(ghBin, args, { stdio: "inherit", env });
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * git-credential-cyrus — git credential helper for multi-org GitHub access.
4
4
  *
5
- * Self-contained Node script (no dependencies). Installed by Cyrus at
5
+ * Node script using the bundled managed-github-auth.cjs policy. Installed at
6
6
  * `<cyrusHome>/scripts/git-credential-cyrus.cjs` and wired into git via:
7
7
  *
8
8
  * git config --global credential."https://github.com".useHttpPath true
@@ -12,15 +12,13 @@
12
12
  * For `get` operations against github.com it looks up the org (first path
13
13
  * segment) in `<cyrusHome>/github-tokens.json` — the per-installation
14
14
  * GitHub App tokens pushed by cyrus-hosted — and prints credentials for a
15
- * case-insensitive org match. If no org matches but exactly one non-expired
16
- * token exists, that token is used. Otherwise it prints nothing and exits 0
17
- * so git falls through to other helpers / prompts.
15
+ * case-insensitive org match. Managed misses return quit=true to stop later
16
+ * helpers/keyrings/prompts. Only an absent, never-enrolled store permits
17
+ * unmanaged credential fallback.
18
18
  */
19
19
  "use strict";
20
20
 
21
21
  const fs = require("node:fs");
22
- const os = require("node:os");
23
- const path = require("node:path");
24
22
 
25
23
  function main() {
26
24
  // Only the `get` operation produces credentials; `store`/`erase` are no-ops.
@@ -46,39 +44,25 @@ function main() {
46
44
  // With credential.useHttpPath=true git sends e.g. path=owner/repo.git
47
45
  const org = (attrs.path || "").split("/")[0] || "";
48
46
 
49
- const cyrusHome = process.env.CYRUS_HOME || path.join(os.homedir(), ".cyrus");
50
- const tokensFile = path.join(cyrusHome, "github-tokens.json");
51
-
52
- let tokens = [];
47
+ let auth;
48
+ let resolveManagedToken;
53
49
  try {
54
- const parsed = JSON.parse(fs.readFileSync(tokensFile, "utf8"));
55
- if (Array.isArray(parsed.tokens)) tokens = parsed.tokens;
50
+ const policy = require("./managed-github-auth.cjs");
51
+ auth = policy.loadManagedAuth();
52
+ resolveManagedToken = policy.resolveManagedToken;
56
53
  } catch {
54
+ process.stdout.write("quit=true\n");
57
55
  return;
58
56
  }
59
-
60
- const now = Date.now();
61
- const valid = tokens.filter((t) => {
62
- if (!t || typeof t.token !== "string" || t.token.length === 0) return false;
63
- const expiresAt = Date.parse(t.expiresAt);
64
- return !Number.isNaN(expiresAt) && expiresAt > now;
65
- });
66
-
67
- let match;
68
- if (org) {
69
- const lowered = org.toLowerCase();
70
- match = valid.find(
71
- (t) =>
72
- typeof t.organization === "string" &&
73
- t.organization.toLowerCase() === lowered,
74
- );
75
- }
76
- if (!match && valid.length === 1) {
77
- match = valid[0];
57
+ if (!auth.managed) return;
58
+ const token = resolveManagedToken(auth.tokens, org);
59
+ if (!token) {
60
+ // An empty response would permit later keyring helpers and askpass prompts.
61
+ process.stdout.write("quit=true\n");
62
+ return;
78
63
  }
79
- if (!match) return;
80
64
 
81
- process.stdout.write(`username=x-access-token\npassword=${match.token}\n`);
65
+ process.stdout.write(`username=x-access-token\npassword=${token}\n`);
82
66
  }
83
67
 
84
68
  main();
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ // Shared by the installed gh resolver and Git credential helper. A present
3
+ // store is authoritative, even when empty/broken. The enrollment marker keeps
4
+ // accidental deletion from silently restoring cached authentication.
5
+ const fs = require("node:fs");
6
+ const os = require("node:os");
7
+ const path = require("node:path");
8
+
9
+ function present(file) {
10
+ try {
11
+ fs.lstatSync(file);
12
+ return true;
13
+ } catch (error) {
14
+ return error.code !== "ENOENT";
15
+ }
16
+ }
17
+
18
+ function loadManagedAuth() {
19
+ const home = process.env.CYRUS_HOME || path.join(os.homedir(), ".cyrus");
20
+ const file = path.join(home, "github-tokens.json");
21
+ const managed =
22
+ present(file) || present(path.join(home, "github-auth-managed"));
23
+ if (!managed) return { managed: false, tokens: [] };
24
+ try {
25
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
26
+ if (parsed.version !== 1 || !Array.isArray(parsed.tokens))
27
+ throw new Error();
28
+ // Refuse the entire malformed snapshot; never reinterpret it as unmanaged.
29
+ if (
30
+ !parsed.tokens.every(
31
+ (t) =>
32
+ t &&
33
+ typeof t.token === "string" &&
34
+ t.token.length > 0 &&
35
+ !/[\s\0]/.test(t.token) &&
36
+ (t.organization === null ||
37
+ (typeof t.organization === "string" &&
38
+ /^[a-z0-9-]+$/i.test(t.organization))) &&
39
+ typeof t.expiresAt === "string" &&
40
+ Number.isFinite(Date.parse(t.expiresAt)),
41
+ )
42
+ )
43
+ throw new Error();
44
+ return {
45
+ managed: true,
46
+ tokens: parsed.tokens.filter((t) => Date.parse(t.expiresAt) > Date.now()),
47
+ };
48
+ } catch {
49
+ return { managed: true, tokens: [] };
50
+ }
51
+ }
52
+
53
+ function resolveManagedToken(tokens, owner, sessionToken) {
54
+ // An explicit owner must never borrow a different installation's credential.
55
+ if (owner)
56
+ return tokens.find(
57
+ (t) => t.organization?.toLowerCase() === owner.toLowerCase(),
58
+ )?.token;
59
+ // Session snapshots are only hints, not an independent source of authority.
60
+ if (sessionToken) return tokens.find((t) => t.token === sessionToken)?.token;
61
+ return tokens.length === 1 ? tokens[0].token : undefined;
62
+ }
63
+ module.exports = { loadManagedAuth, resolveManagedToken };