axauth 1.8.0 → 1.10.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/README.md +1 -1
- package/dist/auth/adapter.d.ts +25 -0
- package/dist/auth/agents/claude-storage.d.ts +12 -2
- package/dist/auth/agents/claude-storage.js +35 -12
- package/dist/auth/agents/claude.js +11 -3
- package/dist/auth/agents/codex-auth-check.d.ts +3 -1
- package/dist/auth/agents/codex-auth-check.js +3 -3
- package/dist/auth/agents/codex-storage.d.ts +1 -1
- package/dist/auth/agents/codex.js +4 -3
- package/dist/auth/agents/copilot-install.d.ts +18 -0
- package/dist/auth/agents/copilot-install.js +73 -0
- package/dist/auth/agents/copilot.js +14 -61
- package/dist/auth/agents/gemini-auth-check.d.ts +3 -1
- package/dist/auth/agents/gemini-auth-check.js +1 -1
- package/dist/auth/agents/gemini.js +14 -3
- package/dist/auth/agents/opencode.js +1 -1
- package/dist/auth/extract-creds-from-directory.js +1 -1
- package/dist/auth/registry.d.ts +8 -0
- package/dist/auth/registry.js +8 -0
- package/dist/auth/types.d.ts +2 -1
- package/dist/auth/types.js +2 -2
- package/dist/auth/validate-directories.d.ts +1 -0
- package/dist/cli.js +98 -2
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/auth.js +31 -13
- package/dist/commands/decrypt.d.ts +13 -0
- package/dist/commands/decrypt.js +69 -0
- package/dist/commands/encrypt.d.ts +13 -0
- package/dist/commands/encrypt.js +75 -0
- package/dist/commands/vault.d.ts +34 -0
- package/dist/commands/vault.js +163 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/vault/vault-client.d.ts +85 -0
- package/dist/vault/vault-client.js +170 -0
- package/dist/vault/vault-config.d.ts +54 -0
- package/dist/vault/vault-config.js +112 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -253,7 +253,7 @@ src/
|
|
|
253
253
|
|
|
254
254
|
## Related Packages
|
|
255
255
|
|
|
256
|
-
axauth is part of the [a╳
|
|
256
|
+
axauth is part of the [a╳kit](https://axkit.dev) ecosystem:
|
|
257
257
|
|
|
258
258
|
- **axshared** - Shared types and agent metadata
|
|
259
259
|
- **axconfig** - Permission and configuration management
|
package/dist/auth/adapter.d.ts
CHANGED
|
@@ -111,6 +111,18 @@ interface AdapterCapabilities {
|
|
|
111
111
|
*
|
|
112
112
|
* Encapsulates all auth operations for a single agent, hiding the
|
|
113
113
|
* complexity of different storage mechanisms and credential formats.
|
|
114
|
+
*
|
|
115
|
+
* ## Credential Source Priority
|
|
116
|
+
*
|
|
117
|
+
* When resolving credentials, sources are checked in this order:
|
|
118
|
+
*
|
|
119
|
+
* 1. **Environment variables** (via `extractFromEnvironment`)
|
|
120
|
+
* 2. **Vault** (external, via axvault server when configured)
|
|
121
|
+
* 3. **Local storage** (keychain/file via `extractRawCredentials`)
|
|
122
|
+
*
|
|
123
|
+
* Environment variables always take precedence to allow easy overrides
|
|
124
|
+
* in CI/CD and development. Vault provides centralized credential
|
|
125
|
+
* management. Local storage is the fallback for interactive use.
|
|
114
126
|
*/
|
|
115
127
|
interface AuthAdapter {
|
|
116
128
|
/** Agent identifier */
|
|
@@ -124,6 +136,19 @@ interface AuthAdapter {
|
|
|
124
136
|
* and returns the status without making API calls.
|
|
125
137
|
*/
|
|
126
138
|
checkAuth(): AuthStatus;
|
|
139
|
+
/**
|
|
140
|
+
* Extract credentials from environment variables only.
|
|
141
|
+
*
|
|
142
|
+
* This is called before checking vault or local storage to ensure
|
|
143
|
+
* environment variables have highest priority. Returns undefined if
|
|
144
|
+
* no credentials are set via environment variables.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* // For Claude, checks CLAUDE_CODE_OAUTH_TOKEN and ANTHROPIC_API_KEY
|
|
148
|
+
* const envCreds = adapter.extractFromEnvironment?.();
|
|
149
|
+
* if (envCreds) return envCreds; // Env vars win over vault
|
|
150
|
+
*/
|
|
151
|
+
extractFromEnvironment?(): Credentials | undefined;
|
|
127
152
|
/**
|
|
128
153
|
* Extract raw credentials for export.
|
|
129
154
|
*
|
|
@@ -18,9 +18,19 @@ declare function checkAuth(): {
|
|
|
18
18
|
method?: string;
|
|
19
19
|
details?: Record<string, unknown>;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Extract credentials from environment variables only.
|
|
23
|
+
*
|
|
24
|
+
* This is called before checking vault or local storage to ensure
|
|
25
|
+
* environment variables have highest priority.
|
|
26
|
+
*/
|
|
27
|
+
declare function extractFromEnvironment(): {
|
|
28
|
+
type: "oauth-credentials" | "oauth-token" | "api-key";
|
|
29
|
+
data: Record<string, unknown>;
|
|
30
|
+
} | undefined;
|
|
21
31
|
/** Extract raw credentials from available sources */
|
|
22
32
|
declare function extractRawCredentials(): {
|
|
23
|
-
type: "oauth" | "api-key";
|
|
33
|
+
type: "oauth-credentials" | "oauth-token" | "api-key";
|
|
24
34
|
data: Record<string, unknown>;
|
|
25
35
|
} | undefined;
|
|
26
|
-
export { AGENT_ID, checkAuth, deleteFileCreds, deleteKeychainCreds, extractRawCredentials, getDefaultCredsFilePath, saveFileCreds, saveKeychainCreds, };
|
|
36
|
+
export { AGENT_ID, checkAuth, deleteFileCreds, deleteKeychainCreds, extractFromEnvironment, extractRawCredentials, getDefaultCredsFilePath, saveFileCreds, saveKeychainCreds, };
|
|
@@ -81,34 +81,57 @@ function checkAuth() {
|
|
|
81
81
|
}
|
|
82
82
|
return { authenticated: false };
|
|
83
83
|
}
|
|
84
|
-
/**
|
|
85
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Extract credentials from environment variables only.
|
|
86
|
+
*
|
|
87
|
+
* This is called before checking vault or local storage to ensure
|
|
88
|
+
* environment variables have highest priority.
|
|
89
|
+
*/
|
|
90
|
+
function extractFromEnvironment() {
|
|
86
91
|
if (process.env.CLAUDE_CODE_OAUTH_TOKEN) {
|
|
87
92
|
return {
|
|
88
|
-
type: "oauth",
|
|
93
|
+
type: "oauth-token",
|
|
89
94
|
data: { accessToken: process.env.CLAUDE_CODE_OAUTH_TOKEN },
|
|
90
95
|
};
|
|
91
96
|
}
|
|
97
|
+
if (process.env.ANTHROPIC_API_KEY) {
|
|
98
|
+
return {
|
|
99
|
+
type: "api-key",
|
|
100
|
+
data: { apiKey: process.env.ANTHROPIC_API_KEY },
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Extract credentials from local storage only (keychain + file).
|
|
107
|
+
*
|
|
108
|
+
* This skips environment variable checks and only looks at local storage.
|
|
109
|
+
* Used as fallback after vault fetch fails.
|
|
110
|
+
*/
|
|
111
|
+
function extractFromLocalStorage() {
|
|
92
112
|
const keychainCreds = loadKeychainCreds();
|
|
93
113
|
if (keychainCreds) {
|
|
94
114
|
return {
|
|
95
|
-
type: "oauth",
|
|
115
|
+
type: "oauth-credentials",
|
|
96
116
|
data: { ...keychainCreds, _source: "keychain" },
|
|
97
117
|
};
|
|
98
118
|
}
|
|
99
119
|
const fileCreds = loadFileCreds();
|
|
100
120
|
if (fileCreds) {
|
|
101
121
|
return {
|
|
102
|
-
type: "oauth",
|
|
122
|
+
type: "oauth-credentials",
|
|
103
123
|
data: { ...fileCreds, _source: "file" },
|
|
104
124
|
};
|
|
105
125
|
}
|
|
106
|
-
if (process.env.ANTHROPIC_API_KEY) {
|
|
107
|
-
return {
|
|
108
|
-
type: "api-key",
|
|
109
|
-
data: { apiKey: process.env.ANTHROPIC_API_KEY },
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
126
|
return undefined;
|
|
113
127
|
}
|
|
114
|
-
|
|
128
|
+
/** Extract raw credentials from available sources */
|
|
129
|
+
function extractRawCredentials() {
|
|
130
|
+
// Check env vars first
|
|
131
|
+
const environmentCreds = extractFromEnvironment();
|
|
132
|
+
if (environmentCreds)
|
|
133
|
+
return environmentCreds;
|
|
134
|
+
// Fall back to local storage
|
|
135
|
+
return extractFromLocalStorage();
|
|
136
|
+
}
|
|
137
|
+
export { AGENT_ID, checkAuth, deleteFileCreds, deleteKeychainCreds, extractFromEnvironment, extractRawCredentials, getDefaultCredsFilePath, saveFileCreds, saveKeychainCreds, };
|
|
@@ -7,7 +7,7 @@ import path from "node:path";
|
|
|
7
7
|
import { extractCredsFromDirectory } from "../extract-creds-from-directory.js";
|
|
8
8
|
import { isMacOS } from "../keychain.js";
|
|
9
9
|
import { resolveCustomDirectory } from "../validate-directories.js";
|
|
10
|
-
import { AGENT_ID, checkAuth, deleteFileCreds, deleteKeychainCreds, extractRawCredentials, getDefaultCredsFilePath, saveFileCreds, saveKeychainCreds, } from "./claude-storage.js";
|
|
10
|
+
import { AGENT_ID, checkAuth, deleteFileCreds, deleteKeychainCreds, extractFromEnvironment, extractRawCredentials, getDefaultCredsFilePath, saveFileCreds, saveKeychainCreds, } from "./claude-storage.js";
|
|
11
11
|
const CREDS_FILE_NAME = ".credentials.json";
|
|
12
12
|
/** Claude Code authentication adapter */
|
|
13
13
|
const claudeCodeAdapter = {
|
|
@@ -22,6 +22,12 @@ const claudeCodeAdapter = {
|
|
|
22
22
|
const result = checkAuth();
|
|
23
23
|
return { agentId: AGENT_ID, ...result };
|
|
24
24
|
},
|
|
25
|
+
extractFromEnvironment() {
|
|
26
|
+
const result = extractFromEnvironment();
|
|
27
|
+
if (!result)
|
|
28
|
+
return undefined;
|
|
29
|
+
return { agent: AGENT_ID, ...result };
|
|
30
|
+
},
|
|
25
31
|
extractRawCredentials() {
|
|
26
32
|
const result = extractRawCredentials();
|
|
27
33
|
if (!result)
|
|
@@ -121,7 +127,8 @@ const claudeCodeAdapter = {
|
|
|
121
127
|
},
|
|
122
128
|
getAccessToken(creds) {
|
|
123
129
|
const data = creds.data;
|
|
124
|
-
if (creds.type === "oauth"
|
|
130
|
+
if ((creds.type === "oauth-credentials" || creds.type === "oauth-token") &&
|
|
131
|
+
typeof data.accessToken === "string") {
|
|
125
132
|
return data.accessToken;
|
|
126
133
|
}
|
|
127
134
|
if (creds.type === "api-key" && typeof data.apiKey === "string") {
|
|
@@ -132,7 +139,8 @@ const claudeCodeAdapter = {
|
|
|
132
139
|
credentialsToEnvironment(creds) {
|
|
133
140
|
const environment = {};
|
|
134
141
|
const data = creds.data;
|
|
135
|
-
if (creds.type === "oauth"
|
|
142
|
+
if ((creds.type === "oauth-credentials" || creds.type === "oauth-token") &&
|
|
143
|
+
typeof data.accessToken === "string") {
|
|
136
144
|
environment.CLAUDE_CODE_OAUTH_TOKEN = data.accessToken;
|
|
137
145
|
}
|
|
138
146
|
else if (creds.type === "api-key" && typeof data.apiKey === "string") {
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import type { AuthStatus, Credentials } from "../types.js";
|
|
5
5
|
/** Check auth status across all sources */
|
|
6
6
|
declare function checkAuth(): AuthStatus;
|
|
7
|
+
/** Extract credentials from environment */
|
|
8
|
+
declare function extractEnvironmentCredentials(): Credentials | undefined;
|
|
7
9
|
/** Extract raw credentials from first available source */
|
|
8
10
|
declare function extractRawCredentials(): Credentials | undefined;
|
|
9
|
-
export { checkAuth, extractRawCredentials };
|
|
11
|
+
export { checkAuth, extractEnvironmentCredentials, extractRawCredentials };
|
|
@@ -71,7 +71,7 @@ function extractKeychainCredentials() {
|
|
|
71
71
|
if (keychainAuth?.tokens) {
|
|
72
72
|
return {
|
|
73
73
|
agent: AGENT_ID,
|
|
74
|
-
type: "oauth",
|
|
74
|
+
type: "oauth-credentials",
|
|
75
75
|
data: { ...keychainAuth, _source: "keychain" },
|
|
76
76
|
};
|
|
77
77
|
}
|
|
@@ -88,7 +88,7 @@ function extractFileCredentials() {
|
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
if (fileAuth?.tokens) {
|
|
91
|
-
return { agent: AGENT_ID, type: "oauth", data: fileAuth };
|
|
91
|
+
return { agent: AGENT_ID, type: "oauth-credentials", data: fileAuth };
|
|
92
92
|
}
|
|
93
93
|
return undefined;
|
|
94
94
|
}
|
|
@@ -98,4 +98,4 @@ function extractRawCredentials() {
|
|
|
98
98
|
extractKeychainCredentials() ??
|
|
99
99
|
extractFileCredentials());
|
|
100
100
|
}
|
|
101
|
-
export { checkAuth, extractRawCredentials };
|
|
101
|
+
export { checkAuth, extractEnvironmentCredentials, extractRawCredentials };
|
|
@@ -39,5 +39,5 @@ interface CredentialsData {
|
|
|
39
39
|
[key: string]: unknown;
|
|
40
40
|
}
|
|
41
41
|
/** Build auth content from credentials data */
|
|
42
|
-
declare function buildAuthContent(type: "oauth" | "api-key", data: CredentialsData): CodexAuthJson;
|
|
42
|
+
declare function buildAuthContent(type: "oauth-credentials" | "oauth-token" | "api-key", data: CredentialsData): CodexAuthJson;
|
|
43
43
|
export { buildAuthContent, deleteFileCreds, deleteKeychainCreds, getEnvironmentApiKey, hasFileApiKey, hasFileOAuth, hasKeychainApiKey, hasKeychainOAuth, loadFileCreds, loadKeychainCreds, saveFileCreds, saveKeychainCreds, };
|
|
@@ -8,7 +8,7 @@ import path from "node:path";
|
|
|
8
8
|
import { ensureDirectory } from "../file-storage.js";
|
|
9
9
|
import { isMacOS } from "../keychain.js";
|
|
10
10
|
import { resolveCustomDirectory } from "../validate-directories.js";
|
|
11
|
-
import { checkAuth, extractRawCredentials } from "./codex-auth-check.js";
|
|
11
|
+
import { checkAuth, extractEnvironmentCredentials, extractRawCredentials, } from "./codex-auth-check.js";
|
|
12
12
|
import { getAuthFilePath, getCodexHome, updateConfigStorage, } from "./codex-config.js";
|
|
13
13
|
import { buildAuthContent, deleteFileCreds, deleteKeychainCreds, saveFileCreds, saveKeychainCreds, } from "./codex-storage.js";
|
|
14
14
|
const AGENT_ID = "codex";
|
|
@@ -23,6 +23,7 @@ const codexAdapter = {
|
|
|
23
23
|
installApiKey: true,
|
|
24
24
|
},
|
|
25
25
|
checkAuth,
|
|
26
|
+
extractFromEnvironment: extractEnvironmentCredentials,
|
|
26
27
|
extractRawCredentials,
|
|
27
28
|
extractRawCredentialsFromDirectory(options) {
|
|
28
29
|
// Codex doesn't separate config/data - use either directory
|
|
@@ -38,7 +39,7 @@ const codexAdapter = {
|
|
|
38
39
|
return undefined;
|
|
39
40
|
const data = parsed;
|
|
40
41
|
// Determine type from data structure
|
|
41
|
-
const type = data.api_key ? "api-key" : "oauth";
|
|
42
|
+
const type = data.api_key ? "api-key" : "oauth-credentials";
|
|
42
43
|
return { agent: AGENT_ID, type, data };
|
|
43
44
|
}
|
|
44
45
|
catch {
|
|
@@ -133,7 +134,7 @@ const codexAdapter = {
|
|
|
133
134
|
if (creds.type === "api-key" && typeof data.apiKey === "string") {
|
|
134
135
|
return data.apiKey;
|
|
135
136
|
}
|
|
136
|
-
if (creds.type === "oauth") {
|
|
137
|
+
if (creds.type === "oauth-credentials") {
|
|
137
138
|
// Direct access_token
|
|
138
139
|
if (typeof data.access_token === "string") {
|
|
139
140
|
return data.access_token;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot credential installation helpers.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from copilot.ts to reduce file complexity.
|
|
5
|
+
*/
|
|
6
|
+
import type { InstallOptions, OperationResult } from "../adapter.js";
|
|
7
|
+
import type { Credentials } from "../types.js";
|
|
8
|
+
import type { ResolveResult } from "../validate-directories.js";
|
|
9
|
+
declare const CREDS_FILE_NAME = "token.json";
|
|
10
|
+
/**
|
|
11
|
+
* Install Copilot credentials.
|
|
12
|
+
*
|
|
13
|
+
* Handles keychain vs file storage and custom directories.
|
|
14
|
+
*/
|
|
15
|
+
declare function installCopilotCredentials(creds: Credentials, resolved: Extract<ResolveResult, {
|
|
16
|
+
ok: true;
|
|
17
|
+
}>, options?: InstallOptions): OperationResult;
|
|
18
|
+
export { CREDS_FILE_NAME, installCopilotCredentials };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copilot credential installation helpers.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from copilot.ts to reduce file complexity.
|
|
5
|
+
*/
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { ensureDirectory } from "../file-storage.js";
|
|
8
|
+
import { isMacOS } from "../keychain.js";
|
|
9
|
+
import { getConfigDirectory, getConfigFilePath, saveFileToken, saveKeychainToken, saveTokenToPath, } from "./copilot-storage.js";
|
|
10
|
+
const CREDS_FILE_NAME = "token.json";
|
|
11
|
+
/**
|
|
12
|
+
* Install Copilot credentials.
|
|
13
|
+
*
|
|
14
|
+
* Handles keychain vs file storage and custom directories.
|
|
15
|
+
*/
|
|
16
|
+
function installCopilotCredentials(creds, resolved, options) {
|
|
17
|
+
if (creds.type === "api-key") {
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
message: "API key credentials cannot be installed (use COPILOT_GITHUB_TOKEN env var)",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const token = typeof creds.data.accessToken === "string"
|
|
24
|
+
? creds.data.accessToken
|
|
25
|
+
: undefined;
|
|
26
|
+
if (!token) {
|
|
27
|
+
return { ok: false, message: "No access token found in credentials" };
|
|
28
|
+
}
|
|
29
|
+
// Custom directory forces file storage
|
|
30
|
+
if (resolved.customDir) {
|
|
31
|
+
const targetPath = path.join(resolved.customDir, CREDS_FILE_NAME);
|
|
32
|
+
if (saveTokenToPath(token, targetPath)) {
|
|
33
|
+
return {
|
|
34
|
+
ok: true,
|
|
35
|
+
message: `Installed credentials to ${targetPath}`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
ok: false,
|
|
40
|
+
message: `Failed to install credentials to ${targetPath}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Default location: use storage option or _source marker
|
|
44
|
+
const sourceMarker = creds.data._source;
|
|
45
|
+
const targetStorage = options?.storage ?? (sourceMarker === "keychain" ? "keychain" : "file");
|
|
46
|
+
if (targetStorage === "keychain") {
|
|
47
|
+
if (!isMacOS()) {
|
|
48
|
+
return {
|
|
49
|
+
ok: false,
|
|
50
|
+
message: "Keychain storage is only available on macOS",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (saveKeychainToken(token)) {
|
|
54
|
+
return { ok: true, message: "Installed credentials to macOS Keychain" };
|
|
55
|
+
}
|
|
56
|
+
return { ok: false, message: "Failed to save to macOS Keychain" };
|
|
57
|
+
}
|
|
58
|
+
// File storage
|
|
59
|
+
if (!ensureDirectory(getConfigDirectory())) {
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
message: "Failed to create copilot config directory",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (saveFileToken(token)) {
|
|
66
|
+
return {
|
|
67
|
+
ok: true,
|
|
68
|
+
message: `Installed credentials to ${getConfigFilePath()}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return { ok: false, message: "Failed to install credentials to file" };
|
|
72
|
+
}
|
|
73
|
+
export { CREDS_FILE_NAME, installCopilotCredentials };
|
|
@@ -6,13 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { extractCredsFromDirectory } from "../extract-creds-from-directory.js";
|
|
9
|
-
import { ensureDirectory } from "../file-storage.js";
|
|
10
|
-
import { isMacOS } from "../keychain.js";
|
|
11
9
|
import { resolveCustomDirectory } from "../validate-directories.js";
|
|
12
10
|
import { findFirstAvailableToken } from "./copilot-auth-check.js";
|
|
13
|
-
import {
|
|
11
|
+
import { CREDS_FILE_NAME, installCopilotCredentials, } from "./copilot-install.js";
|
|
12
|
+
import { deleteFileToken, deleteKeychainToken, deleteTokenFromPath, getConfigFilePath, getEnvironmentToken, } from "./copilot-storage.js";
|
|
14
13
|
const AGENT_ID = "copilot";
|
|
15
|
-
const CREDS_FILE_NAME = "token.json";
|
|
16
14
|
/** Copilot CLI authentication adapter */
|
|
17
15
|
const copilotAdapter = {
|
|
18
16
|
agentId: AGENT_ID,
|
|
@@ -39,13 +37,23 @@ const copilotAdapter = {
|
|
|
39
37
|
method: methodMap[result.source],
|
|
40
38
|
};
|
|
41
39
|
},
|
|
40
|
+
extractFromEnvironment() {
|
|
41
|
+
const token = getEnvironmentToken();
|
|
42
|
+
if (!token)
|
|
43
|
+
return undefined;
|
|
44
|
+
return {
|
|
45
|
+
agent: AGENT_ID,
|
|
46
|
+
type: "oauth-token",
|
|
47
|
+
data: { accessToken: token },
|
|
48
|
+
};
|
|
49
|
+
},
|
|
42
50
|
extractRawCredentials() {
|
|
43
51
|
const result = findFirstAvailableToken();
|
|
44
52
|
if (!result)
|
|
45
53
|
return undefined;
|
|
46
54
|
return {
|
|
47
55
|
agent: AGENT_ID,
|
|
48
|
-
type: "oauth",
|
|
56
|
+
type: "oauth-token",
|
|
49
57
|
data: { accessToken: result.token, _source: result.source },
|
|
50
58
|
};
|
|
51
59
|
},
|
|
@@ -57,65 +65,10 @@ const copilotAdapter = {
|
|
|
57
65
|
return extractCredsFromDirectory(AGENT_ID, directory, CREDS_FILE_NAME);
|
|
58
66
|
},
|
|
59
67
|
installCredentials(creds, options) {
|
|
60
|
-
// Resolve custom directory with validation
|
|
61
68
|
const resolved = resolveCustomDirectory(AGENT_ID, options?.configDir, options?.dataDir);
|
|
62
69
|
if (!resolved.ok)
|
|
63
70
|
return resolved.error;
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
ok: false,
|
|
67
|
-
message: "API key credentials cannot be installed (use COPILOT_GITHUB_TOKEN env var)",
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
const token = typeof creds.data.accessToken === "string"
|
|
71
|
-
? creds.data.accessToken
|
|
72
|
-
: undefined;
|
|
73
|
-
if (!token) {
|
|
74
|
-
return { ok: false, message: "No access token found in credentials" };
|
|
75
|
-
}
|
|
76
|
-
// Custom directory forces file storage
|
|
77
|
-
if (resolved.customDir) {
|
|
78
|
-
const targetPath = path.join(resolved.customDir, CREDS_FILE_NAME);
|
|
79
|
-
if (saveTokenToPath(token, targetPath)) {
|
|
80
|
-
return {
|
|
81
|
-
ok: true,
|
|
82
|
-
message: `Installed credentials to ${targetPath}`,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
ok: false,
|
|
87
|
-
message: `Failed to install credentials to ${targetPath}`,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
// Default location: use storage option or _source marker
|
|
91
|
-
const sourceMarker = creds.data._source;
|
|
92
|
-
const targetStorage = options?.storage ?? (sourceMarker === "keychain" ? "keychain" : "file");
|
|
93
|
-
if (targetStorage === "keychain") {
|
|
94
|
-
if (!isMacOS()) {
|
|
95
|
-
return {
|
|
96
|
-
ok: false,
|
|
97
|
-
message: "Keychain storage is only available on macOS",
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
if (saveKeychainToken(token)) {
|
|
101
|
-
return { ok: true, message: "Installed credentials to macOS Keychain" };
|
|
102
|
-
}
|
|
103
|
-
return { ok: false, message: "Failed to save to macOS Keychain" };
|
|
104
|
-
}
|
|
105
|
-
// File storage
|
|
106
|
-
if (!ensureDirectory(getConfigDirectory())) {
|
|
107
|
-
return {
|
|
108
|
-
ok: false,
|
|
109
|
-
message: "Failed to create copilot config directory",
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
if (saveFileToken(token)) {
|
|
113
|
-
return {
|
|
114
|
-
ok: true,
|
|
115
|
-
message: `Installed credentials to ${getConfigFilePath()}`,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
return { ok: false, message: "Failed to install credentials to file" };
|
|
71
|
+
return installCopilotCredentials(creds, resolved, options);
|
|
119
72
|
},
|
|
120
73
|
removeCredentials(options) {
|
|
121
74
|
// Resolve custom directory with validation
|
|
@@ -11,6 +11,8 @@ interface CredentialResult {
|
|
|
11
11
|
method: string;
|
|
12
12
|
data?: Record<string, unknown>;
|
|
13
13
|
}
|
|
14
|
+
/** Check environment variable credentials (API key and Vertex AI) */
|
|
15
|
+
declare function checkEnvironmentAuth(): CredentialResult | undefined;
|
|
14
16
|
/** Find credentials using priority-ordered discovery: env → keychain → file */
|
|
15
17
|
declare function findCredentials(): CredentialResult | undefined;
|
|
16
|
-
export { findCredentials };
|
|
18
|
+
export { checkEnvironmentAuth, findCredentials };
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Supports OAuth via keychain (macOS) or file. API key auth is env-var only.
|
|
5
5
|
*/
|
|
6
6
|
import { extractCredsFromDirectory } from "../extract-creds-from-directory.js";
|
|
7
|
-
import { findCredentials } from "./gemini-auth-check.js";
|
|
7
|
+
import { checkEnvironmentAuth, findCredentials } from "./gemini-auth-check.js";
|
|
8
8
|
import { installOAuthCredentials, removeGeminiCredentials, } from "./gemini-install.js";
|
|
9
9
|
const AGENT_ID = "gemini";
|
|
10
10
|
/** Gemini authentication adapter */
|
|
@@ -27,6 +27,16 @@ const geminiAdapter = {
|
|
|
27
27
|
method: result.method,
|
|
28
28
|
};
|
|
29
29
|
},
|
|
30
|
+
extractFromEnvironment() {
|
|
31
|
+
const result = checkEnvironmentAuth();
|
|
32
|
+
if (!result || !result.data)
|
|
33
|
+
return undefined;
|
|
34
|
+
return {
|
|
35
|
+
agent: AGENT_ID,
|
|
36
|
+
type: "api-key",
|
|
37
|
+
data: result.data,
|
|
38
|
+
};
|
|
39
|
+
},
|
|
30
40
|
extractRawCredentials() {
|
|
31
41
|
const result = findCredentials();
|
|
32
42
|
if (!result || !result.data)
|
|
@@ -42,7 +52,7 @@ const geminiAdapter = {
|
|
|
42
52
|
// OAuth credentials from keychain or file include _source for round-tripping
|
|
43
53
|
return {
|
|
44
54
|
agent: AGENT_ID,
|
|
45
|
-
type: "oauth",
|
|
55
|
+
type: "oauth-credentials",
|
|
46
56
|
data: {
|
|
47
57
|
...result.data,
|
|
48
58
|
_source: result.source === "keychain" ? "keychain" : "file",
|
|
@@ -74,7 +84,8 @@ const geminiAdapter = {
|
|
|
74
84
|
if (creds.type === "api-key" && typeof data.apiKey === "string") {
|
|
75
85
|
return data.apiKey;
|
|
76
86
|
}
|
|
77
|
-
if (creds.type === "oauth" &&
|
|
87
|
+
if (creds.type === "oauth-credentials" &&
|
|
88
|
+
typeof data.access_token === "string") {
|
|
78
89
|
return data.access_token;
|
|
79
90
|
}
|
|
80
91
|
return undefined;
|
|
@@ -77,7 +77,7 @@ const opencodeAdapter = {
|
|
|
77
77
|
const auth = readAuthFile(getDefaultAuthFilePath());
|
|
78
78
|
if (!auth || Object.keys(auth).length === 0)
|
|
79
79
|
return undefined;
|
|
80
|
-
return { agent: AGENT_ID, type: "oauth", data: auth };
|
|
80
|
+
return { agent: AGENT_ID, type: "oauth-credentials", data: auth };
|
|
81
81
|
},
|
|
82
82
|
extractRawCredentialsFromDirectory(options) {
|
|
83
83
|
// OpenCode stores credentials in dataDir only - configDir is for settings
|
|
@@ -28,7 +28,7 @@ function extractCredsFromDirectory(agentId, directory, fileName, transform) {
|
|
|
28
28
|
const data = transform ? transform(record) : record;
|
|
29
29
|
if (!data)
|
|
30
30
|
return undefined;
|
|
31
|
-
return { agent: agentId, type: "oauth", data };
|
|
31
|
+
return { agent: agentId, type: "oauth-credentials", data };
|
|
32
32
|
}
|
|
33
33
|
catch {
|
|
34
34
|
return undefined;
|
package/dist/auth/registry.d.ts
CHANGED
|
@@ -51,9 +51,17 @@ declare function checkAllAuth(): AuthStatus[];
|
|
|
51
51
|
/**
|
|
52
52
|
* Extract raw credentials for an agent.
|
|
53
53
|
*
|
|
54
|
+
* Checks credentials from all available sources:
|
|
55
|
+
* - Environment variables
|
|
56
|
+
* - Keychain (macOS)
|
|
57
|
+
* - File storage
|
|
58
|
+
*
|
|
54
59
|
* Note: The `data` field format is agent-specific and not standardized.
|
|
55
60
|
* Use {@link getAccessToken} to extract the token in a uniform way.
|
|
56
61
|
*
|
|
62
|
+
* For vault credentials, use {@link fetchVaultCredentials} from the vault module
|
|
63
|
+
* or the `axauth vault fetch` CLI command.
|
|
64
|
+
*
|
|
57
65
|
* @example
|
|
58
66
|
* const creds = extractRawCredentials("codex");
|
|
59
67
|
* if (creds) { await exportCredentials(creds); }
|
package/dist/auth/registry.js
CHANGED
|
@@ -75,9 +75,17 @@ function checkAllAuth() {
|
|
|
75
75
|
/**
|
|
76
76
|
* Extract raw credentials for an agent.
|
|
77
77
|
*
|
|
78
|
+
* Checks credentials from all available sources:
|
|
79
|
+
* - Environment variables
|
|
80
|
+
* - Keychain (macOS)
|
|
81
|
+
* - File storage
|
|
82
|
+
*
|
|
78
83
|
* Note: The `data` field format is agent-specific and not standardized.
|
|
79
84
|
* Use {@link getAccessToken} to extract the token in a uniform way.
|
|
80
85
|
*
|
|
86
|
+
* For vault credentials, use {@link fetchVaultCredentials} from the vault module
|
|
87
|
+
* or the `axauth vault fetch` CLI command.
|
|
88
|
+
*
|
|
81
89
|
* @example
|
|
82
90
|
* const creds = extractRawCredentials("codex");
|
|
83
91
|
* if (creds) { await exportCredentials(creds); }
|
package/dist/auth/types.d.ts
CHANGED
|
@@ -21,8 +21,9 @@ declare const Credentials: z.ZodObject<{
|
|
|
21
21
|
copilot: "copilot";
|
|
22
22
|
}>;
|
|
23
23
|
type: z.ZodEnum<{
|
|
24
|
-
oauth: "oauth";
|
|
25
24
|
"api-key": "api-key";
|
|
25
|
+
"oauth-token": "oauth-token";
|
|
26
|
+
"oauth-credentials": "oauth-credentials";
|
|
26
27
|
}>;
|
|
27
28
|
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
28
29
|
}, z.core.$strip>;
|
package/dist/auth/types.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared types for auth module.
|
|
3
3
|
*/
|
|
4
|
-
import { AGENT_CLIS } from "axshared";
|
|
4
|
+
import { AGENT_CLIS, CredentialType } from "axshared";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
/** Zod schema for AgentCli */
|
|
7
7
|
const AgentCliSchema = z.enum(AGENT_CLIS);
|
|
8
8
|
/** Extracted credential data schema */
|
|
9
9
|
const Credentials = z.object({
|
|
10
10
|
agent: AgentCliSchema,
|
|
11
|
-
type:
|
|
11
|
+
type: CredentialType,
|
|
12
12
|
data: z.record(z.string(), z.unknown()),
|
|
13
13
|
});
|
|
14
14
|
/**
|
|
@@ -22,4 +22,5 @@ type ResolveResult = {
|
|
|
22
22
|
* @see resolveCustomDirectories in axshared for behavior details
|
|
23
23
|
*/
|
|
24
24
|
declare function resolveCustomDirectory(agentId: AgentCli, configDirectory: string | undefined, dataDirectory: string | undefined): ResolveResult;
|
|
25
|
+
export type { ResolveResult };
|
|
25
26
|
export { resolveCustomDirectory };
|