Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails (#35094)
This commit is contained in:
@@ -147,6 +147,181 @@ describe("pairing setup code", () => {
|
||||
expect(resolved.payload.token).toBe("tok_123");
|
||||
});
|
||||
|
||||
it("resolves gateway.auth.token SecretRef for pairing payload", async () => {
|
||||
const resolved = await resolvePairingSetupFromConfig(
|
||||
{
|
||||
gateway: {
|
||||
bind: "custom",
|
||||
customBindHost: "gateway.local",
|
||||
auth: {
|
||||
mode: "token",
|
||||
token: { source: "env", provider: "default", id: "GW_TOKEN" },
|
||||
},
|
||||
},
|
||||
secrets: {
|
||||
providers: {
|
||||
default: { source: "env" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
env: {
|
||||
GW_TOKEN: "resolved-token",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(resolved.ok).toBe(true);
|
||||
if (!resolved.ok) {
|
||||
throw new Error("expected setup resolution to succeed");
|
||||
}
|
||||
expect(resolved.authLabel).toBe("token");
|
||||
expect(resolved.payload.token).toBe("resolved-token");
|
||||
});
|
||||
|
||||
it("errors when gateway.auth.token SecretRef is unresolved in token mode", async () => {
|
||||
await expect(
|
||||
resolvePairingSetupFromConfig(
|
||||
{
|
||||
gateway: {
|
||||
bind: "custom",
|
||||
customBindHost: "gateway.local",
|
||||
auth: {
|
||||
mode: "token",
|
||||
token: { source: "env", provider: "default", id: "MISSING_GW_TOKEN" },
|
||||
},
|
||||
},
|
||||
secrets: {
|
||||
providers: {
|
||||
default: { source: "env" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
env: {},
|
||||
},
|
||||
),
|
||||
).rejects.toThrow(/MISSING_GW_TOKEN/i);
|
||||
});
|
||||
|
||||
it("uses password env in inferred mode without resolving token SecretRef", async () => {
|
||||
const resolved = await resolvePairingSetupFromConfig(
|
||||
{
|
||||
gateway: {
|
||||
bind: "custom",
|
||||
customBindHost: "gateway.local",
|
||||
auth: {
|
||||
token: { source: "env", provider: "default", id: "MISSING_GW_TOKEN" },
|
||||
},
|
||||
},
|
||||
secrets: {
|
||||
providers: {
|
||||
default: { source: "env" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
env: {
|
||||
OPENCLAW_GATEWAY_PASSWORD: "password-from-env",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(resolved.ok).toBe(true);
|
||||
if (!resolved.ok) {
|
||||
throw new Error("expected setup resolution to succeed");
|
||||
}
|
||||
expect(resolved.authLabel).toBe("password");
|
||||
expect(resolved.payload.password).toBe("password-from-env");
|
||||
});
|
||||
|
||||
it("does not treat env-template token as plaintext in inferred mode", async () => {
|
||||
const resolved = await resolvePairingSetupFromConfig(
|
||||
{
|
||||
gateway: {
|
||||
bind: "custom",
|
||||
customBindHost: "gateway.local",
|
||||
auth: {
|
||||
token: "${MISSING_GW_TOKEN}",
|
||||
},
|
||||
},
|
||||
secrets: {
|
||||
providers: {
|
||||
default: { source: "env" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
env: {
|
||||
OPENCLAW_GATEWAY_PASSWORD: "password-from-env",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(resolved.ok).toBe(true);
|
||||
if (!resolved.ok) {
|
||||
throw new Error("expected setup resolution to succeed");
|
||||
}
|
||||
expect(resolved.authLabel).toBe("password");
|
||||
expect(resolved.payload.token).toBeUndefined();
|
||||
expect(resolved.payload.password).toBe("password-from-env");
|
||||
});
|
||||
|
||||
it("requires explicit auth mode when token and password are both configured", async () => {
|
||||
await expect(
|
||||
resolvePairingSetupFromConfig(
|
||||
{
|
||||
gateway: {
|
||||
bind: "custom",
|
||||
customBindHost: "gateway.local",
|
||||
auth: {
|
||||
token: { source: "env", provider: "default", id: "GW_TOKEN" },
|
||||
password: { source: "env", provider: "default", id: "GW_PASSWORD" },
|
||||
},
|
||||
},
|
||||
secrets: {
|
||||
providers: {
|
||||
default: { source: "env" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
env: {
|
||||
GW_TOKEN: "resolved-token",
|
||||
GW_PASSWORD: "resolved-password",
|
||||
},
|
||||
},
|
||||
),
|
||||
).rejects.toThrow(/gateway\.auth\.mode is unset/i);
|
||||
});
|
||||
|
||||
it("errors when token and password SecretRefs are both configured with inferred mode", async () => {
|
||||
await expect(
|
||||
resolvePairingSetupFromConfig(
|
||||
{
|
||||
gateway: {
|
||||
bind: "custom",
|
||||
customBindHost: "gateway.local",
|
||||
auth: {
|
||||
token: { source: "env", provider: "default", id: "MISSING_GW_TOKEN" },
|
||||
password: { source: "env", provider: "default", id: "GW_PASSWORD" },
|
||||
},
|
||||
},
|
||||
secrets: {
|
||||
providers: {
|
||||
default: { source: "env" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
env: {
|
||||
GW_PASSWORD: "resolved-password",
|
||||
},
|
||||
},
|
||||
),
|
||||
).rejects.toThrow(/gateway\.auth\.mode is unset/i);
|
||||
});
|
||||
|
||||
it("honors env token override", async () => {
|
||||
const resolved = await resolvePairingSetupFromConfig(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user