mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
feat: expose provider auth evidence lookup
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
import {
|
||||
listKnownProviderAuthEnvVarNames,
|
||||
resolveProviderAuthEvidence,
|
||||
resolveProviderAuthEnvVarCandidates,
|
||||
} from "../secrets/provider-env-vars.js";
|
||||
import type { ProviderEnvVarLookupParams } from "../secrets/provider-env-vars.js";
|
||||
import type {
|
||||
ProviderAuthEvidence,
|
||||
ProviderEnvVarLookupParams,
|
||||
} from "../secrets/provider-env-vars.js";
|
||||
|
||||
export function resolveProviderEnvApiKeyCandidates(
|
||||
params?: ProviderEnvVarLookupParams,
|
||||
@@ -10,6 +14,12 @@ export function resolveProviderEnvApiKeyCandidates(
|
||||
return resolveProviderAuthEnvVarCandidates(params);
|
||||
}
|
||||
|
||||
export function resolveProviderEnvAuthEvidence(
|
||||
params?: ProviderEnvVarLookupParams,
|
||||
): Record<string, readonly ProviderAuthEvidence[]> {
|
||||
return resolveProviderAuthEvidence(params);
|
||||
}
|
||||
|
||||
export const PROVIDER_ENV_API_KEY_CANDIDATES = resolveProviderEnvApiKeyCandidates();
|
||||
|
||||
export function listKnownProviderEnvApiKeyNames(): string[] {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
listKnownSecretEnvVarNames,
|
||||
PROVIDER_AUTH_ENV_VAR_CANDIDATES,
|
||||
PROVIDER_ENV_VARS,
|
||||
resolveProviderAuthEvidence,
|
||||
} from "./provider-env-vars.js";
|
||||
|
||||
type MockManifestRegistry = {
|
||||
@@ -19,6 +20,15 @@ type MockManifestRegistry = {
|
||||
providers?: Array<{
|
||||
id: string;
|
||||
envVars?: string[];
|
||||
authEvidence?: Array<{
|
||||
type: "local-file-with-env";
|
||||
fileEnvVar?: string;
|
||||
fallbackPaths?: string[];
|
||||
requiresAnyEnv?: string[];
|
||||
requiresAllEnv?: string[];
|
||||
credentialMarker: string;
|
||||
source?: string;
|
||||
}>;
|
||||
}>;
|
||||
};
|
||||
}>;
|
||||
@@ -107,6 +117,44 @@ describe("provider env vars dynamic manifest metadata", () => {
|
||||
expect(listKnownSecretEnvVarNames()).toContain("MODEL_STUDIO_API_KEY");
|
||||
});
|
||||
|
||||
it("includes setup provider auth evidence without loading setup runtime", async () => {
|
||||
pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry.mockReturnValue({
|
||||
plugins: [
|
||||
{
|
||||
id: "external-cloud",
|
||||
origin: "global",
|
||||
setup: {
|
||||
providers: [
|
||||
{
|
||||
id: "external-cloud",
|
||||
authEvidence: [
|
||||
{
|
||||
type: "local-file-with-env",
|
||||
fileEnvVar: "EXTERNAL_CLOUD_CREDENTIALS",
|
||||
requiresAllEnv: ["EXTERNAL_CLOUD_PROJECT"],
|
||||
credentialMarker: "external-cloud-local-credentials",
|
||||
source: "external cloud credentials",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
diagnostics: [],
|
||||
});
|
||||
|
||||
expect(resolveProviderAuthEvidence()["external-cloud"]).toEqual([
|
||||
{
|
||||
type: "local-file-with-env",
|
||||
fileEnvVar: "EXTERNAL_CLOUD_CREDENTIALS",
|
||||
requiresAllEnv: ["EXTERNAL_CLOUD_PROJECT"],
|
||||
credentialMarker: "external-cloud-local-credentials",
|
||||
source: "external cloud credentials",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("appends setup provider env vars after explicit provider auth env vars", async () => {
|
||||
pluginRegistryMocks.loadPluginManifestRegistryForInstalledIndex.mockReturnValue({
|
||||
plugins: [
|
||||
|
||||
@@ -29,6 +29,16 @@ export type ProviderEnvVarLookupParams = {
|
||||
includeUntrustedWorkspacePlugins?: boolean;
|
||||
};
|
||||
|
||||
export type ProviderAuthEvidence = {
|
||||
type: "local-file-with-env";
|
||||
fileEnvVar?: string;
|
||||
fallbackPaths?: readonly string[];
|
||||
requiresAnyEnv?: readonly string[];
|
||||
requiresAllEnv?: readonly string[];
|
||||
credentialMarker: string;
|
||||
source?: string;
|
||||
};
|
||||
|
||||
function isWorkspacePluginTrustedForProviderEnvVars(
|
||||
plugin: PluginManifestRecord,
|
||||
config: OpenClawConfig | undefined,
|
||||
@@ -73,6 +83,27 @@ function appendUniqueEnvVarCandidates(
|
||||
}
|
||||
}
|
||||
|
||||
function appendUniqueAuthEvidence(
|
||||
target: Record<string, ProviderAuthEvidence[]>,
|
||||
providerId: string,
|
||||
evidence: readonly ProviderAuthEvidence[],
|
||||
) {
|
||||
const normalizedProviderId = providerId.trim();
|
||||
if (!normalizedProviderId || evidence.length === 0) {
|
||||
return;
|
||||
}
|
||||
const bucket = (target[normalizedProviderId] ??= []);
|
||||
const seen = new Set(bucket.map((entry) => JSON.stringify(entry)));
|
||||
for (const entry of evidence) {
|
||||
const key = JSON.stringify(entry);
|
||||
if (seen.has(key)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(key);
|
||||
bucket.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveManifestProviderAuthEnvVarCandidates(
|
||||
params?: ProviderEnvVarLookupParams,
|
||||
): Record<string, string[]> {
|
||||
@@ -111,6 +142,37 @@ function resolveManifestProviderAuthEnvVarCandidates(
|
||||
return candidates;
|
||||
}
|
||||
|
||||
function resolveManifestProviderAuthEvidence(
|
||||
params?: ProviderEnvVarLookupParams,
|
||||
): Record<string, ProviderAuthEvidence[]> {
|
||||
const registry = loadPluginManifestRegistryForPluginRegistry({
|
||||
config: params?.config,
|
||||
workspaceDir: params?.workspaceDir,
|
||||
env: params?.env,
|
||||
preferPersisted: false,
|
||||
includeDisabled: true,
|
||||
});
|
||||
const evidenceByProvider: Record<string, ProviderAuthEvidence[]> = {};
|
||||
for (const plugin of registry.plugins) {
|
||||
if (!shouldUsePluginProviderEnvVars(plugin, params)) {
|
||||
continue;
|
||||
}
|
||||
for (const provider of plugin.setup?.providers ?? []) {
|
||||
appendUniqueAuthEvidence(evidenceByProvider, provider.id, provider.authEvidence ?? []);
|
||||
}
|
||||
}
|
||||
const aliases = resolveProviderAuthAliasMap(params);
|
||||
for (const [alias, target] of Object.entries(aliases).toSorted(([left], [right]) =>
|
||||
left.localeCompare(right),
|
||||
)) {
|
||||
const evidence = evidenceByProvider[target];
|
||||
if (evidence) {
|
||||
appendUniqueAuthEvidence(evidenceByProvider, alias, evidence);
|
||||
}
|
||||
}
|
||||
return evidenceByProvider;
|
||||
}
|
||||
|
||||
export function resolveProviderAuthEnvVarCandidates(
|
||||
params?: ProviderEnvVarLookupParams,
|
||||
): Record<string, readonly string[]> {
|
||||
@@ -120,6 +182,12 @@ export function resolveProviderAuthEnvVarCandidates(
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveProviderAuthEvidence(
|
||||
params?: ProviderEnvVarLookupParams,
|
||||
): Record<string, readonly ProviderAuthEvidence[]> {
|
||||
return resolveManifestProviderAuthEvidence(params);
|
||||
}
|
||||
|
||||
export function resolveProviderEnvVars(
|
||||
params?: ProviderEnvVarLookupParams,
|
||||
): Record<string, readonly string[]> {
|
||||
|
||||
Reference in New Issue
Block a user