filiptrivan/spiderly/api-keys
Claude Code and agent skill by filiptrivan/spiderly
- community
Checking that the SKILL.md file is still in the repository.
Add the API-keys feature to a Spiderly app — per-key authentication via an X-Api-Key header, where each key is a first-class principal carrying its own roles. Use when a project needs machine/partner/agent access to its REST API (generate, scope-to-roles, expire, revoke). Opt-in; not part of the default app.
Install
npx vskill@latest install filiptrivan/spiderly/api-keysSKILL.md
Add API Keys
This builds the API-keys feature into a Spiderly consumer app: external clients authenticate with an X-Api-Key header, and each key is a first-class principal (PrincipalKinds.ApiKey) that carries its own roles — it is not an impersonation of a user. Authorization resolves a key's permissions through the same principal pipeline as a user, so [AuthGuard("code")] endpoints accept either a JWT or a key with no per-endpoint change.
This is opt-in. API keys are not part of a default Spiderly app — nothing here exists until you run this skill, and an app without it has zero API-key surface. Don't add it unless the project actually needs machine/partner/agent API access.
Why a key is a principal (read once)
An API key must be individually revocable and separately expirable — a stateless token (e.g. a long-lived JWT) can't be revoked without either rotating the signing key (logging out every user) or a per-request denylist. So a key is an opaque random secret, stored hashed, checked against a row on every request. The framework owns that mechanism (Spiderly.Security); this skill assembles the per-app pieces on top.
Modeling the key as its own ISecurityPrincipal (rather than "resolve to the owning user + cap permissions") means:
- The key's authority = the union of its own roles' permissions. A role-less key has no permissions.
- The owning
Useris just management metadata (who created/lists/revokes it), decoupled from authority. - No runtime permission-cap machinery — authorization treats the key like any other principal.
Step 0 — Prerequisites
- Spiderly version — confirm the compiled mechanism is present. It must expose
Spiderly.Security.Authentication.IApiKeyAuthenticator, theAddApiKeys<TApiKey>()sub-builder onSpiderlySecurityBuilder, andPrincipalKinds.ApiKey. If those don't resolve, the app is on too old a Spiderly version — upgrade first (see thespiderly-upgradeskill). - The app must already use Spiderly auth — its
Startup.cscallsspiderly.AddSecurity<User, UserExternalLogin, AuthorizationService>(…), which registers the humanUserprincipal and enables authentication. API keys add a second principal kind alongside it.
Decide with the user up front: do they want an admin UI to manage keys, or API/agent-only (drive generation via the REST endpoints / a management skill)? The backend is identical either way; the UI is the optional Step 8.
Step 1 — The ApiKey entity (+ junction + navs)
Create the entity in the Business project's Entities/. Adapt the namespace and the User/Role types to the app.
IApiKey (which extends ISecurityPrincipal) is Spiderly.Security.Interfaces; IRole is Spiderly.Shared.Interfaces. The entity implements IApiKey so the framework's default authenticator (Step 2) reads it generically.
Add the M2M junction (mirrors the app's UserRole):
Add the inverse M2M nav public virtual List<ApiKey> ApiKeys { get; } = new(); // M2M on `Role`. There is no nav on User — the creator is a soft reference (id + kind), not a navigation.
Step 2 — The authenticator (you don't write one)
The framework ships DefaultApiKeyAuthenticator<TApiKey>, which does the hash→active-id lookup over your ApiKey entity generically (it reads it via the IApiKey interface, so it stays decoupled from your namespace). You get it for free from the Step 4 registration — there is no authenticator to hand-write.
Only implement your own IApiKeyAuthenticator for a non-standard lookup (e.g. an external key store). If you do, register it before the AddApiKeys<ApiKey>() call (Step 4) — the framework adds the default with TryAdd, so your registration wins.
Step 3 — ApiKeyService hooks (generate + hash + show-once)
Extend the generated ApiKeyServiceGenerated so the admin/CRUD save path mints the key, stores only its hash, and returns the plaintext exactly once:
ApiKeyHelper is Spiderly.Security.Authentication. If the app's authorization service has a different class name, inject that.
Step 4 — Register the key (API-keys sub-builder)
Pass an s => s.AddApiKeys<ApiKey>() configurator to the existing spiderly.AddSecurity<…>(…) call in Startup.cs:
AddApiKeys<ApiKey>() registers the ApiKey principal kind and the authentication scheme in one call — the ApiKey scheme plus a forwarding policy scheme set as the default, so X-Api-Key requests route to the key handler and everything else to JWT, with no per-endpoint [Authorize(AuthenticationSchemes=...)] churn. Registering a second principal kind makes the app multi-principal; the JWT login already stamps PrincipalKinds.User, the key handler stamps PrincipalKinds.ApiKey, so both satisfy the now-required principal_kind claim.
Step 5 — The issuance guard (authorization service)
In the app's authorization service (the [SpiderlyService] extending AuthorizationServiceGenerated), add the guard the UpdateRolesForApiKey override and the Generate endpoint both call:
Add the ApiKeyRoleExceedsYourPermissionsException translation key (see the backend-localization doc).
Step 6 — Generate / Revoke endpoints + DTOs
These are the machine-facing REST surface (also what a management skill drives). Add to a [SpiderlyController] (e.g. the security controller). DTOs go in the Admin DTO folder; the PlainTextKey extension is a partial of the generated ApiKeyMainUIFormDTO and must use the bare ...Business.DTO namespace (see the entity-design doc on partial-DTO namespacing).
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingclaude-plugins/skills/api-keys/SKILL.md
Popularity
- Repository stars
- 60
- Repository forks
- 24
- 7-day trend score
- 21
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/filiptrivan/spiderly/api-keys)