Skip to content

[codex] Show secret usage and link to source edit#341

Draft
heyglassy wants to merge 12 commits intoRhysSullivan:mainfrom
heyglassy:codex/secrets-usage-links
Draft

[codex] Show secret usage and link to source edit#341
heyglassy wants to merge 12 commits intoRhysSullivan:mainfrom
heyglassy:codex/secrets-usage-links

Conversation

@heyglassy
Copy link
Copy Markdown
Contributor

@heyglassy heyglassy commented Apr 20, 2026

Summary

  • add secret usage metadata to the Secrets API by deriving source-to-secret relationships from persisted source configs
  • render an In use dropdown on the Secrets page that lists linked sources and lets users jump straight to the source detail/edit screen
  • include a screenshot of the working UI flow captured in Helium with Computer Use

Why

Secrets already knew which provider stored them, but not which configured sources referenced them. This made it hard to answer "is this safe to remove?" and required manual cross-checking against source configs.

Validation

  • bunx vitest run --config vitest.node.config.ts src/services/secrets-api.node.test.ts in apps/cloud
  • verified in the local app at https://executor-local.localhost:1355/secrets
  • verified with Computer Use in Helium that clicking Vercel API from the In use dropdown navigates to /sources/vercel_api

Screenshot

![Secrets page showing the In use dropdown for a secret]
CleanShot 2026-04-20 at 09 25 48@2x

Expose source usage information from the secrets list API by deriving secret-to-source relationships from persisted source configs across OpenAPI, GraphQL, MCP, and Google Discovery sources. Render that metadata in the shared Secrets page as an In use trigger with a dropdown listing the linked sources, and add a cloud API regression test covering an OpenAPI-backed secret usage case.
Update the Secrets page usage dropdown so linked source entries navigate to /sources/$namespace. This lets users jump directly from a secret to the source detail/edit screen for the source that references it.
Move secret usage discovery out of packages/core/api into app-owned HTTP layers and plugin-owned extractors. This keeps core secrets APIs generic while local/cloud compose usage metadata from installed plugins for the secrets UI.
Comment on lines +24 to +42
const isSecretRef = (value: unknown): value is { readonly secretId: string } =>
typeof value === "object" &&
value !== null &&
"secretId" in value &&
typeof value.secretId === "string";

const collectHeaderSecretIds = (headers: unknown): readonly string[] => {
if (!headers || typeof headers !== "object") return [];
const secretIds = new Set<string>();
for (const value of Object.values(headers)) {
if (isSecretRef(value)) {
secretIds.add(value.secretId);
}
}
return [...secretIds];
};

const asRecord = (value: unknown): Record<string, unknown> | null =>
value !== null && typeof value === "object" ? (value as Record<string, unknown>) : null;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clean up the codex slop

Comment on lines +109 to +126
const getStoredSource = (
executor: Record<string, any>,
pluginId: string,
sourceId: string,
scopeId: string,
) => {
switch (pluginId) {
case "openapi":
return executor.openapi?.getSource?.(sourceId, scopeId);
case "graphql":
return executor.graphql?.getSource?.(sourceId, scopeId);
case "mcp":
return executor.mcp?.getSource?.(sourceId, scopeId);
case "googleDiscovery":
return executor.googleDiscovery?.getSource?.(sourceId, scopeId);
default:
return undefined;
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see if you can make this plugin agnostic or implement in plugins in some way - llm is getting lazy here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CleanShot 2026-04-20 at 10 17 33@2x

<3

Add ReactivityKey.sources to the route-local secretsUsageAtom queries in cloud and local. The secrets usage payload is derived from source configuration, so source mutations need to invalidate this query immediately instead of waiting for the 30-second TTL.
Make the cloud and local secrets routes render from the secrets query independently of the supplementary secretsUsage query.

When secrets load successfully, the page now always renders the secrets list. Usage metadata is treated as optional and falls back to an empty array while usage is still loading or has failed, so mergeSecrets still produces secrets with empty usedBy arrays instead of forcing the whole page into loading or error.

Verified with bun run typecheck in apps/cloud. apps/local typecheck is currently blocked by an unrelated existing error in packages/plugins/onepassword/src/react/OnePasswordSettings.tsx for missing CircleHelp.
Fix the workspace issues uncovered while validating the secrets usage changes before push.

This removes two unused-variable lint warnings in core handlers/tests, renames the shared react secrets-usage API module from .tsx to .ts so server-side packages can import it without JSX resolution errors, and adds an explicit @executor/react export entry for that module so local/cloud packages resolve it through the package exports map during typecheck.

Verified with bun run lint and bun run typecheck at the workspace root.
Cloud secrets usage was reloading source configs only from the current inner scope even though executor.sources.list() already returns sources visible across the full cloud scope stack. That caused inherited org-level OpenAPI, GraphQL, and MCP sources to disappear from the usage scan when a member viewed /secrets from their user-org scope.

Update the secrets usage handler to resolve stored source configs across executor.scopes in order, so inner-scope overrides still win while inherited org-scoped sources remain visible. Add a cloud node test covering the member/user-scope case for an inherited org-scoped source.
…explicit in shared source projections and use it across the secrets usage flow and source UI. This should remove the cloud-specific inherited-scope scan, let source detail/edit read and write the owning scope directly, and reduce duplicated secrets route wiring between local and cloud.
…cit @executor/react api export for secrets-usage now that the file lives at src/api/secrets-usage.tsx and is covered by the existing ./api/* export map. Keep the rename in this working copy and verify the package still typechecks.
…tsPage presentation logic by replacing the nested ternary state rendering with a small helper function. This keeps the route-level Result shaping unchanged and makes the page component easier to scan without changing behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants