fix(secrets): describe --show-values resolves through the backend driver
Some checks failed
Some checks failed
Post-migration, every Secret on a non-plaintext backend has empty `Secret.data` (the actual value lives in the backend; only externalRef is on the row). `describe secret --show-values` was reading the raw row, so the user saw "Data: (empty)" for every migrated secret. - Route GET /api/v1/secrets/:id accepts ?reveal=true; when set, resolves the value via SecretService.resolveData() so the response carries the actual data dispatched through the right driver. - CLI --show-values flips that query param. Without --show-values the route returns the raw row exactly as before (no leak risk). Caught running the wizard end-to-end on the live cluster after the ClusterMesh fix on the kubernetes-deployment side made bao reachable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -928,7 +928,15 @@ export function createDescribeCommand(deps: DescribeCommandDeps): Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const item = await deps.fetchResource(resource, id) as Record<string, unknown>;
|
let item: Record<string, unknown>;
|
||||||
|
if (resource === 'secrets' && opts.showValues === true) {
|
||||||
|
// --show-values needs the resolved data (the raw row's `data` is
|
||||||
|
// empty for non-plaintext backends — values live in the backend).
|
||||||
|
// Use ?reveal=true so mcpd dispatches through the backing driver.
|
||||||
|
item = await deps.client.get<Record<string, unknown>>(`/api/v1/secrets/${id}?reveal=true`);
|
||||||
|
} else {
|
||||||
|
item = await deps.fetchResource(resource, id) as Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
// Enrich instances with container inspect data
|
// Enrich instances with container inspect data
|
||||||
let inspect: Record<string, unknown> | undefined;
|
let inspect: Record<string, unknown> | undefined;
|
||||||
|
|||||||
@@ -9,9 +9,25 @@ export function registerSecretRoutes(
|
|||||||
return service.list();
|
return service.list();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get<{ Params: { id: string } }>('/api/v1/secrets/:id', async (request) => {
|
app.get<{ Params: { id: string }; Querystring: { reveal?: string } }>(
|
||||||
return service.getById(request.params.id);
|
'/api/v1/secrets/:id',
|
||||||
});
|
async (request) => {
|
||||||
|
const secret = await service.getById(request.params.id);
|
||||||
|
// ?reveal=true → resolve `data` through the backing driver. Without
|
||||||
|
// reveal we return the raw row, which for non-plaintext backends has
|
||||||
|
// an empty `data` (the real values live in the backend; only the
|
||||||
|
// externalRef is on the row). The CLI's `describe secret` already
|
||||||
|
// masks values by default; --show-values flips this query param so the
|
||||||
|
// describe output matches what the user expects pre/post migration.
|
||||||
|
if (request.query.reveal === 'true') {
|
||||||
|
const resolved = await service.resolveData(secret).catch(() => null);
|
||||||
|
if (resolved !== null) {
|
||||||
|
return { ...secret, data: resolved };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return secret;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
app.post('/api/v1/secrets', async (request, reply) => {
|
app.post('/api/v1/secrets', async (request, reply) => {
|
||||||
const secret = await service.create(request.body);
|
const secret = await service.create(request.body);
|
||||||
|
|||||||
Reference in New Issue
Block a user