fix(exe-dev): skip PEM validation when sshPrivateKey is a saved secret-ref UUID (PAPA-407)

When the operator picks a saved secret in the JsonSchemaForm, the persisted value is
the bare UUID of the secret record, not the PEM. Run-time secret resolution swaps in
the actual key before SSH, but config save-time validation was rejecting the UUID as
an invalid PEM. Skip PEM checks when the value matches the server-side secret-ref
UUID regex.
This commit is contained in:
Devin Foley committed 2026-05-29 17:37:52 -07:00
1 parent bf8a7c98ea
commit fe9cd6bcd6
2 files changed
+26 -1

No files matched your search

@@ -202,6 +202,26 @@ describe("exe.dev sandbox provider plugin", () => {
expect(validateSshPrivateKey(VALID_RSA_PEM)).toBeNull();
});
it("accepts UUID-like secret reference values from the save-time schema stage", async () => {
process.env.EXE_API_KEY = "host-key";
const result = await plugin.definition.onEnvironmentValidateConfig?.({
driverKey: "exe-dev",
config: {
apiKey: "api-key",
sshPrivateKey: "11111111-1111-4111-8111-111111111111",
},
});
expect(result).toMatchObject({
ok: true,
normalizedConfig: {
sshPrivateKey: "11111111-1111-4111-8111-111111111111",
},
});
expect(result?.errors ?? []).toEqual([]);
});
it("treats empty / whitespace-only input as valid (falls back to on-host key)", () => {
expect(validateSshPrivateKey("")).toBeNull();
expect(validateSshPrivateKey(" \n\n ")).toBeNull();
@@ -69,6 +69,7 @@ const MAX_VM_RECORD_DEPTH = 4;
const EXE_DEV_SSH_ONBOARDING_MARKER = "Please complete registration by running: ssh exe.dev";
const EXE_DEV_SSH_EMAIL_PROMPT = "Please enter your email address:";
const EXE_DEV_SSH_INVALID_KEY_FORMAT = /Load key [^\n]*invalid format/i;
const UUID_SECRET_REF_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
// exe.dev's `--setup-script` runs at VM init as the unprivileged `exedev` user, which
// has passwordless sudo. The Paperclip sandbox callback bridge is a Node script, so
@@ -140,6 +141,10 @@ function isValidUrl(value: string): boolean {
}
}
function isSecretRef(value: string): boolean {
return UUID_SECRET_REF_RE.test(value);
}
// Catch the SSH-key paste failure modes we've seen in the wild (wrong file,
// PPK export, truncated paste) before the user pays the cost of provisioning a
// VM and getting a cryptic SSH error. Inline parse — no `ssh-keygen` dependency
@@ -758,7 +763,7 @@ const plugin = definePlugin({
) {
errors.push("strictHostKeyChecking cannot be empty.");
}
if (config.sshPrivateKey) {
if (config.sshPrivateKey && !isSecretRef(config.sshPrivateKey)) {
const sshKeyError = validateSshPrivateKey(config.sshPrivateKey);
if (sshKeyError) errors.push(sshKeyError);
}