Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
prompts
{
  "listChanged": true
}
resources
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
scan_pathA

Runs Kelp's static engine over a filesystem path. Detects hardcoded secrets (Stripe, AWS, GitHub, OpenAI, Anthropic, Supabase service_role, private keys, and more), Supabase edge functions that skip JWT verification, and recons Supabase edge-fn deployables. Fast, offline, deterministic. Returns findings sorted by severity.

scan_snippetA

Runs the static engine on one in-memory string as if it were a file. Use this after generating code, before showing it to the user or committing it. Cheaper than scan_path when only a diff is at stake.

list_rulesA

Returns the catalog of rules Kelp can fire on. Use this to introspect coverage before scanning, or to answer 'does Kelp check X?' without running a scan.

explain_findingA

Given a ruleId (and optionally the finding's path + preview), returns the reasoning ('why this matters') and a concrete remediation you can turn into a code change or an instruction to the user.

explain_ruleA

Given a ruleId, returns the rule's title, class, severity, why-it-matters, and remediation pattern. Use before or after a scan to understand a rule without an active finding.

Prompts

Interactive templates invoked by user choice

NameDescription
review-repoAsk the assistant to run Kelp over a project and summarize the critical and high findings with concrete remediation.
harden-fileAsk the assistant to scan one file, then rewrite it in place to remove any critical or high finding.

Resources

Contextual data attached and managed by the client

NameDescription
rules-catalogEvery detection rule Kelp knows about, as JSON.
stripe-secret-liveA live Stripe secret key can charge cards, refund customers, and read your live payment data. Once it is public on GitHub it is compromised, even after removal, because the git object is still fetchable.
stripe-secret-testTest-mode keys cannot charge real cards but still expose your test data and give attackers a working handle into your Stripe account structure.
stripe-webhook-secretA leaked whsec_ lets anyone forge signed webhook payloads and bypass the receiving service's authenticity check, which means arbitrary state changes can be triggered by an attacker.
aws-access-key-idEven alone, an AWS access key id narrows the search space. Combined with the very common paired secret key leak, this becomes a full account takeover vector.
github-tokenA leaked GitHub token can read private repos, push code, and open PRs as the token owner. On a CI account, that is a supply-chain compromise.
github-pat-fineFine-grained PATs are still bearer tokens. Their narrower scope reduces blast radius but does not remove it, especially if the token has repo write.
anthropic-keyAn Anthropic API key can spend the account's balance and read message history. Costs can escalate to hundreds of dollars in hours if abused.
openai-project-keysk-proj-... project keys have organization-wide blast radius on the OpenAI side and can be used to spend the balance.
openai-keyA leaked OpenAI key can spend account balance and access model usage history.
google-api-keyGoogle / Firebase API keys are usually origin-restricted on the client, but an unrestricted key or one used server-side can incur billing and expose services.
slack-tokenSlack tokens can read messages, post as bots, and depending on scope, invite users or exfiltrate DM history.
private-key-blockA PEM-formatted private key in the repo means whichever service uses that keypair is now impersonable by any reader of the repo.
supabase-service-roleThe service_role key bypasses RLS and gives read plus write to every table in the project. If it ships to the browser or leaks to GitHub, the database is fully compromised.
jwt-exposedA JWT in source code is either a session token that should never be committed, or a signing artifact whose secret is likely near.
high-entropy-stringThe value looks like a credential by shape and entropy but does not match a known provider pattern. Likely still a secret, treat as suspicious until proven otherwise.
rls_disabledThe table lives in the `public` schema (reachable through PostgREST) and does not have RLS enabled. Any caller with the anon key can read and write every row.
permissive_policyThe table has an ownership column and a policy that uses `USING (true)` or `WITH CHECK (true)` for a client role. RLS is enabled but the policy grants access to every row.
owner_not_scopedThe table has an obvious owner column (user_id, owner_id, tenant_id, etc.) but none of the client-facing policies check `auth.uid() = <owner_column>`. Rows are probably not tenant-scoped.
rls_no_policiesRLS is on but the table has zero policies for anon or authenticated. Postgres defaults to deny, so the API refuses the table entirely.
fk_leak_to_unprotectedAn RLS-protected parent table has a foreign key to a target table that has RLS disabled. A PostgREST caller can embed the target through the FK (e.g. ?select=parent(*,child(*))) and read every row of the target even though the parent is protected.
command_scope_gapA table has RLS enabled, a SELECT policy that scopes reads to the owner, but no policy for INSERT/UPDATE/DELETE while a GRANT still lets a client role write. Reads are safe, writes are wide open.
storage_public_bucketThe bucket is created with `public = true`. Every object in it is served over Supabase's CDN without authentication. Anyone who guesses or captures a path (from HTML, an error log, a shared link) can download the file. Common accidental leak of user-uploaded documents, private avatars, or attachments.
storage_policy_missing_user_scopeA policy on `storage.objects` filters on `bucket_id = 'X'` but never checks `auth.uid()`, `owner`, or `auth.jwt()`. Every authenticated caller can read or write every other user's files in that bucket. Common mistake when copying tutorials that stop at 'restrict to bucket'.
storage_policy_permissiveA policy on `storage.objects` uses `USING (true)` or `WITH CHECK (true)` for a client-facing role. Any authenticated caller reaches every file in the entire storage.objects table, ignoring bucket and owner.
view_bypasses_rlsA `CREATE VIEW` over an RLS-protected base table without `WITH (security_invoker = true)` runs with the view owner's policies (usually postgres), which bypasses RLS on the base table entirely.
supabase-config-verify-jwt-falseverify_jwt = false in supabase/config.toml disables the built-in JWT verification for that function, meaning it accepts any unauthenticated caller. Usually a mistake, sometimes a public-by-design function that then must gate on a shared secret in the handler.
route_handler_no_authAn exported route handler (app/**/route.ts or a legacy pages/api/** default export) has no recognized authentication call anywhere in the file: no getUser/getSession, no requireUser helper, no verified webhook signature. Mutations (POST/PUT/PATCH/DELETE) reachable without a session let any caller write on behalf of anyone; an unauthenticated GET that touches a backend leaks other users' data. This is a heuristic: auth enforced only in middleware or an imported wrapper will read as a false positive, so treat it as a lead to confirm, not proof.
server_action_no_authA "use server" action reads formData (or touches a backend) with no recognized authentication call. Server actions are public POST endpoints the framework exposes to any caller, not just the form they were written for, so an unauthenticated action lets anyone invoke the write with a crafted request. Heuristic, same caveat as route handlers.
firebase_rule_publicA Firestore or Storage security rule uses `allow ...: if true`, so the collection or bucket path is open to the entire internet with no authentication. Critical when it grants a write (anyone can overwrite or delete every document in the path), high when it is a public read (anyone can dump the collection). This is the Firebase equivalent of a `USING (true)` RLS policy.
firebase_rule_unauthenticated_writeA Firestore/Storage rule allows a write (write/create/update/delete) with a condition that never references `request.auth`, so an unauthenticated caller can write as long as the non-auth constraints pass. Payload validation is not authentication.
firebase_rule_write_no_ownerA rule requires the caller to be signed in but never binds the write to the document owner, so any authenticated user can overwrite anyone else's data. The Firebase version of an RLS policy that checks the JWT exists but not `auth.uid()`. Heuristic: rules that delegate to a user-defined `function()` helper are treated as guarded and not flagged.
client_exposed_secretA var named with a public prefix (NEXT_PUBLIC_, VITE_, REACT_APP_, EXPO_PUBLIC_, and friends) is inlined into the client bundle by the build tool, so its value ships to every visitor. When the name is a backend secret (SERVICE_ROLE, SECRET_KEY, PRIVATE_KEY, PASSWORD), that secret is readable by anyone. A Supabase service_role key exposed this way bypasses Row Level Security entirely: full read/write on the whole database from the browser. Anon and publishable keys are public by design and are not flagged.
open_redirectA redirect sink (next/navigation redirect, NextResponse.redirect, res.redirect, location assignment) is fed a target that comes from the request (a query param or other user input) with no allowlist or relative-path check. An attacker sends a link to the trusted domain that bounces the victim to an attacker-controlled site; in an OAuth/auth callback it can carry the code or token off-site. High severity in an auth/callback file. Heuristic: files with a relative-path guard, an origin comparison, or a named allowlist/validator are not flagged.
cors_reflect_credentialsThe response echoes the request's Origin header into Access-Control-Allow-Origin and sets Access-Control-Allow-Credentials: true. Any website the victim visits can make credentialed cross-origin requests and read the response, so it can steal authenticated data. The real, exploitable CORS bug.
cors_wildcard_credentialsAccess-Control-Allow-Origin is '*' while Access-Control-Allow-Credentials is true. Browsers reject this exact combination, so it usually gets 'fixed' by reflecting the Origin, which is the exploitable case. A loud misconfiguration worth fixing before it becomes origin reflection.
cors_wildcardAccess-Control-Allow-Origin is '*', so any website can read this endpoint's responses cross-origin. Fine for a genuinely public, unauthenticated API; a smell on anything that returns user-specific data.

TDQS

A4.2/5.0

Scored across 5 tools

Disambiguation4/5

Each tool has a distinct core purpose: scanning paths vs snippets, listing rules, and explaining rules vs findings. The pairings scan_path/scan_snippet and explain_rule/explain_finding have some surface similarity, but descriptions clarify their boundaries.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: scan_path, scan_snippet, list_rules, explain_rule, explain_finding. The naming is predictable and makes the toolset easy to navigate.

Tool Count5/5

Five tools is well-scoped for a security scanning server: two scan entry points, one rule catalog query, and two explanation helpers. Each tool serves a clear, non-redundant role in the workflow.

Completeness5/5

The toolset covers the full lifecycle expected of a static analysis scanner: discover rules, scan a path or snippet, retrieve rule details, and explain findings with remediation. There are no obvious missing operations for the stated domain.

Maintenance

ActivityMaintained
ResponsivenessResponsive