Add Ghost-issued revocable agent credentials, Settings UI, and Claude MCP plugin - #372
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d4bd8b2fdc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const generated = createAgentToken(); | ||
| const credential = await prisma.agentCredential.create({ |
There was a problem hiding this comment.
Record credential lifecycle in the audit log
When a user creates or revokes an agent credential, these routes only mutate AgentCredential and never append an AuditEvent; consequently, credential issuance and revocation are absent from the hash-chained organizational audit trail, making security investigations unable to verify these sensitive lifecycle actions. Record both POST and DELETE operations in the audit chain, ideally atomically with their credential mutations.
AGENTS.md reference: AGENTS.md:L101-L105
Useful? React with 👍 / 👎.
| await prisma.agentCredential.update({ | ||
| where: { id: credential.id }, | ||
| data: { lastUsedAt: new Date() }, | ||
| }); |
There was a problem hiding this comment.
Throttle credential last-used writes
When a credential-backed agent polls get_run or makes concurrent read-only calls, every request performs this unconditional database update. That turns each credential into a hot row and generates write/WAL traffic for otherwise read-only requests, so normal polling or a noisy client can serialize calls and place disproportionate load on Postgres. Update lastUsedAt only when it is older than a reasonable interval, or record usage asynchronously.
Useful? React with 👍 / 👎.
| <Button disabled={!name.trim()} onClick={createCredential}> | ||
| Create credential | ||
| </Button> |
There was a problem hiding this comment.
Disable credential creation while the request is pending
On a slow connection, double-clicking this still-enabled button sends concurrent POST requests and creates multiple valid credentials. Because each completion overwrites the single token state, only one plaintext remains visible while the other active credential's secret is irretrievably lost, forcing the user to identify and revoke the orphan. Track the pending request and disable the create control until it completes.
Useful? React with 👍 / 👎.
| --- | ||
| description: Use Ghost to find, preview, start, and monitor governed business workflows. Use when the user asks Claude to perform an operation through Ghost or inspect a Ghost run. | ||
| --- |
There was a problem hiding this comment.
Add the required name to the Claude skill
Claude Agent Skills require both name and description in SKILL.md frontmatter, but this skill declares only the description. The skill loader can therefore reject or omit run-workflow, leaving the README's advertised /ghost:run-workflow command unavailable even if the plugin's MCP server connects successfully. Add a valid name: run-workflow field.
Useful? React with 👍 / 👎.
Motivation
GHOST_ACCESS_TOKENenvironment variable.Description
AgentCredentialPrisma model and migration to persist revocable credentials withtokenHash,tokenHint,expiresAt,lastUsedAt, andrevokedAtfields, and wire relations toUserandOrganization.@ghost/core(createAgentTokenandhashAgentToken) and export them from the package.resolveAgentPrincipal, including membership check andlastUsedAtupdate.GET /api/settings/agent-credentials,POST /api/settings/agent-credentials, andDELETE /api/settings/agent-credentials/[id]that enforce session auth and handle creation/listing/revocation.AgentCredentials) to create, list, and revoke credentials and inject it into the Settings page UI.cloud/apps/mcp), web docs, and tooling to use the newGHOST_ACCESS_TOKENenv var instead ofGHOST_AGENT_API_KEY/org/user envs, and add a bundled Claude Code plugin with a stdio MCP shim (plugins/claude-code/ghost).cloud/turbo.jsonto includeGHOST_ACCESS_TOKENinglobalEnvand add package exports for./agent-credentials.packages/core/src/agent/credentials.test.tsto validate token generation and hashing behavior.Testing
@ghost/corevia the repo test runner,pnpm -w test, which includespackages/core/src/agent/credentials.test.ts, and the test passed.pnpm -w build/pnpm -w typecheck) during development and reported no errors.Codex Task