Stash Postgres
cipherstash/stack
Query EQL v3 encrypted columns from hand-written Postgres SQL over pg (node-postgres) or postgres (postgres-js) — no ORM.
A skill your agent uses whenever code will build, return, fetch, or execute SQL that runs against a user's real Postgres database — even when the request reads like an ordinary feature or bug fix…
$ npx skills add supabase/supabase --skill safe-sql-execution -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install supabase/supabase safe-sql-execution --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/supabase/supabase.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/safe-sql-execution .claude/skills/safe-sql-execution && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "safe-sql-execution" agent skill from https://github.com/supabase/supabase/tree/master/.agents/skills/safe-sql-execution into .claude/skills/safe-sql-execution/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "safe-sql-execution", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/supabase/supabase/tree/master/.agents/skills/safe-sql-executionType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add supabase/supabase --skill safe-sql-execution -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install supabase/supabase safe-sql-execution --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/supabase/supabase.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/safe-sql-execution .agents/skills/safe-sql-execution && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "safe-sql-execution" agent skill from https://github.com/supabase/supabase/tree/master/.agents/skills/safe-sql-execution into .agents/skills/safe-sql-execution/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "safe-sql-execution", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add supabase/supabase --skill safe-sql-execution -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install supabase/supabase safe-sql-execution --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/supabase/supabase.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/safe-sql-execution .cursor/skills/safe-sql-execution && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "safe-sql-execution" agent skill from https://github.com/supabase/supabase/tree/master/.agents/skills/safe-sql-execution into .cursor/skills/safe-sql-execution/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "safe-sql-execution", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/supabase/supabase.git --path .agents/skills/safe-sql-execution--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add supabase/supabase --skill safe-sql-execution -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install supabase/supabase safe-sql-execution --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/supabase/supabase.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/safe-sql-execution .gemini/skills/safe-sql-execution && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "safe-sql-execution" agent skill from https://github.com/supabase/supabase/tree/master/.agents/skills/safe-sql-execution into .gemini/skills/safe-sql-execution/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "safe-sql-execution", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install supabase/supabase safe-sql-executionInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add supabase/supabase --skill safe-sql-execution -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/supabase/supabase.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/safe-sql-execution .github/skills/safe-sql-execution && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "safe-sql-execution" agent skill from https://github.com/supabase/supabase/tree/master/.agents/skills/safe-sql-execution into .github/skills/safe-sql-execution/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "safe-sql-execution", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add supabase/supabase --skill safe-sql-execution -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install supabase/supabase safe-sql-execution --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/supabase/supabase.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/safe-sql-execution .opencode/skills/safe-sql-execution && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "safe-sql-execution" agent skill from https://github.com/supabase/supabase/tree/master/.agents/skills/safe-sql-execution into .opencode/skills/safe-sql-execution/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "safe-sql-execution", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
safe-sql-executionA skill your agent uses whenever code will build, return, fetch, or execute SQL that runs against a user's real Postgres database — even when the request reads like an ordinary feature or bug fix…
Safe SQL Execution is an agent skill from supabase/supabase, published by the product's own GitHub organization. Use whenever code will build, return, fetch, or execute SQL that runs against a user's real Postgres database — even when the request reads like an ordinary feature or bug fix and never says "security," "injection," or "SafeSqlFragment." This covers: writing or editing any pg-meta function, query builder, or endpoint that builds/returns SQL for database objects (tables, views, functions, DB triggers, indexes, RLS policies); interpolating a schema/table/column/search/route-param value into SQL text; storing…
Its SKILL.md is about 4.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Databases, covering SQL, Debugging and Forms and validation. It works with SQL, Supabase and PostgreSQL. The repository describes itself as: The Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications. The licence is Apache-2.0.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 26c838a. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Safe SQL Execution loads about 4.2k tokens when it runs. Until then it costs about 258 tokens; SKILL.md has 1,334 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from supabase/supabase at commit 26c838a, republished under its Apache-2.0 licence (© supabase). 1,334 words, ~4,181 tokens.
.claude/skills/safe-sql-execution/SKILL.md (or your agent's skills folder).Supabase Studio executes SQL statements directly against the user's database. Because this is the authenticated user's own database, our security model is different from most frontend applications: a user should be able to execute any SQL statement, as long as it is proven that they themselves authored it. What we SHOULD NOT ALLOW is execution of SQL statements that can be influenced by an attacker, such as through URL parameters.
The security model for SQL execution in Supabase Studio is based on the principle of "proven authorship". This means that a user should only be able to execute SQL statements that they have explicitly authored, and not statements that can be influenced by external input.
There are three classes of SQL fragments:
Hardcoded within the application code. These are safe to execute because
they cannot be influenced by an attacker. They can be marked with the
safeSql utility with pg-meta:
import { safeSql } from '@supabase/pg-meta'
const sql = safeSql`
SELECT *
FROM users
WHERE id = 1
`safeSql automatically creates a string of the branded type
SafeSqlFragment. (See Provenance Tracking below.)
Third-party influenceable. These are SQL fragments that can be influenced
by an attacker, such as through URL parameters or LLM output. These should
be marked with the untrustedSql utility with pg-meta:
import { untrustedSql } from '@supabase/pg-meta'
const unsafeQuery = searchParams.get('query')
const querySql = untrustedSql(unsafeQuery)untrustedSql creates a string of the branded type UntrustedSqlFragment.
(See Provenance Tracking below.)
User-authored. These are SQL fragments that are authored by the user themselves within the UI, for example in a text input field. Because the user is the author, these should be considered safe to execute.
However, there is a caveat, where third-party and user-authored code can mix, contaminating the user-authored code (for example, if an input is prefilled from an unsanitized URL parameter). Provenance tracking helps us track these cases.
For example, a safe input component could be implemented as follows by requiring that its placeholder and controlled value are of type SafeSqlFragment. In this case we can use its onChange to promote the user input to SafeSqlFragment type, because we know that the user is the author of the input. An implementation of this is in
@apps/studio/components/ui/SafeSqlInput.tsx:
import { rawSql, type SafeSqlFragment } from '@supabase/pg-meta'
import type { ChangeEvent, ComponentProps } from 'react'
import { Input } from 'ui-patterns/DataInputs/Input'
type InputProps = ComponentProps<typeof Input>
export type SafeSqlInputProps = Omit<
InputProps, 'placeholder' | 'value' | 'onChange'
> & {
placeholder?: SafeSqlFragment
value: SafeSqlFragment
onChange?:
(event: ChangeEvent<HTMLInputElement>, value: SafeSqlFragment) => void
}
export const SafeSqlInput = ({ onChange, ...props }: SafeSqlInputProps) => (
<Input
{...props}
onChange={(event) => onChange?.(event, rawSql(event.target.value))}
/>
)This is pretty much the ONLY VALID USE CASE of the rawSql export from pg-meta, and it should be used with caution.
Branded types are used to track the provenance of SQL fragments. The types,
exported from pg-meta, are:
SafeSqlFragment: represents SQL fragments that are safe to execute, because
they are either hardcoded in the application or authored by the user
themselves.UntrustedSqlFragment: represents SQL fragments that can be influenced by an
attacker, such as through URL parameters or LLM output.These are valid ways to generate a SafeSqlFragment:
safeSql utility from pg-meta to create hardcoded SQL fragments.pg-meta to sanitize untrusted input
and promote it to a SafeSqlFragment:identliteralkeywordjoinSqlFragments (from pg-meta)trimSafeSqlFragment (from apps/studio/lib/sql.ts)UntrustedSqlFragments can be generated from raw strings using
untrustedSql().
There is also a union type, DisplayableSqlFragment, which represents SQL fragments that can be safely displayed in the UI, but not necessarily executed. This includes both SafeSqlFragment and UntrustedSqlFragment.
SQL derived directly from catalog tables (e.g., function definitions, RLS expressions, etc.) is considered safe, and it is promoted AT THE POINT OF BEING QUERIED from the database. In most cases, this is in an apps/studio/data/*/.ts file, in the utility function that makes the API or database fetch.
A critical exception to the safety of SQL round-tripped from the database is
user snippets. These must NEVER BE CONSIDERED SAFE because they are both (a)
externally influenceable and (b) auto-saved. The snippet type uses the
unchecked_sql property, which is an UntrustedSqlFragment, to enforce this.
SafeSqlFragment typeGiven an insecure string or UntrustedSqlFragment, how do we promote it safely
to a SafeSqlFragment?
This is the preferred method when the input is sanitizable, e.g., it is a relation name, a column name, will be compared as a literal, etc.
The pg-meta library provides the following sanitization utilities that can be
used to safely promote untrusted input to SafeSqlFragment:
ident: for sanitizing identifiers such as table names or column names.literal: for sanitizing literal values that will be used in SQL statements.keyword: for sanitizing SQL keywords.acceptUntrustedSqlSome untrusted SQL fragments cannot be sanitized with the above utilities. For
example, the USING expression in the RLS policy editor is an arbitrary SQL
expression.
In these cases, we can promote the SQL fragment upon explicit user action. User action indicates that the user has seen the SQL and is OK with running it. For example, an explicit user action could be clicking a "Run" button.
The promotion happens with the acceptUntrustedSql utility from pg-meta,
which takes an UntrustedSqlFragment and returns a SafeSqlFragment.
This utility MUST ONLY BE USED IN event handlers. It should NEVER be used in a useQuery, direct in the render body of a component, in a useEffect, or anywhere it could auto-run without explicit user action.
This is safe:
import { acceptUntrustedSql } from '@supabase/pg-meta'
function SafeComponent() {
const { mutate: execute } = useExecuteSqlMutation()
const handleRun = () => {
// ✅ GOOD: Safe because it is in an event handler which requires a user
// click
execute({ sql: acceptUntrustedSql(/* sql */) })
}
return (
<button onClick={handleRun}>Run</button>
)
}This is unsafe:
import { acceptUntrustedSql } from '@supabase/pg-meta'
function UnsafeComponent() {
const { data } = useQuery({
queryKey: ['execute-sql', sql],
queryFn: () => {
// 🛑 BAD: Unsafe because it is in a query which could auto-run without
// explicit user action
return execute({ sql: acceptUntrustedSql(/* sql */) })
},
})
}SQL run against the user's Postgres database runs through the executeSql
function, which only takes arguments of type SafeSqlFragment for the SQL
parameter. Raw strings or UntrustedSqlFragments will error at compile time.
// ✅ GOOD: Automatically safe with `safeSql` utility
const selectStatement = safeSql`select 1`// ✅ GOOD: `pg-meta` utilities sanitize the input
const tableName = ident(userInputTableName)
const searchString = literal(userInputSearchString)
const sqlStatement = safeSql`
SELECT *
FROM ${tableName}
WHERE search_column = ${searchString}
`// 🛑 BAD: Passing raw strings will type error
const tableName = 'my_table'
const sqlStatement = safeSql`
SELECT *
FROM ${tableName}
`// ✅ GOOD: SafeSqlInput only allows a value that is a SafeSqlFragment
import { SafeSqlInput } from '@apps/studio/components/ui/SafeSqlInput'
function MyComponent() {
const [sql, setSql] = useState<SafeSqlFragment>(safeSql``)
return (
<SafeSqlInput
placeholder={safeSql`Enter your SQL query here...`}
value={sql}
onChange={(event, value) => setSql(value)}
/>
)
}// 🛑 BAD: This input mixes SafeSqlFragments and unsafe strings
function MyBadComponent() {
const [sql, setSql] = useState<SafeSqlFragment>(safeSql``)
return (
<Input
// 🛑 BAD: This is unsafe because the placeholder is a raw string
placeholder="Enter your SQL query here..."
value={sql}
onChange={(event) => setSql(event.target.value)}
/>
)
}// ✅ GOOD: SQL from the database is promoted to SafeSqlFragment at the point
// of fetching
// data/function-definitions.ts
function markFunctionDefinitionSafe(
functionDefinition: FunctionDefinition
): SafeFunctionDefinition {
return {
...functionDefinition,
definition: functionDefinition.definition as SafeSqlFragment,
}
}
// data/function-definitions.ts
function getFunctionDefinitions() {
return GET(`/function-definitions`).then((functionDefinitions) =>
functionDefinitions.map(markFunctionDefinitionSafe)
)
}// 🛑 BAD: Strings are promoted to SafeSqlFragment in a utility function, where
// it is impossible to easily determine the safety of the input
// utils.ts
function markFunctionDefinitionSafe(
functionDefinition: FunctionDefinition
): SafeFunctionDefinition {
return {
...functionDefinition,
definition: functionDefinition.definition as SafeSqlFragment,
}
}
// Component.ts
function MyComponent() {
const { data: functionDefinitions } = useFunctionDefinitions()
const safeFunctionDefinitions = functionDefinitions.map(markFunctionDefinitionSafe)
}Snippets are auto-persisted to the database and can be created or modified
through externally influenceable channels (e.g., prefilled from URL params).
The unchecked_sql property is typed as UntrustedSqlFragment to enforce this
— it must only be promoted to SafeSqlFragment via acceptUntrustedSql in an
event handler that requires explicit user action.
// 🛑 BAD: Snippet content is executed automatically via useQuery, with no
// explicit user action confirming that the user has reviewed the SQL.
import { acceptUntrustedSql } from '@supabase/pg-meta'
function UnsafeSnippetPreview({ snippet }: { snippet: Snippet }) {
const { data } = useExecuteSqlQuery({
sql: acceptUntrustedSql(snippet.content.unchecked_sql),
})
return <Results data={data} />
}// 🛑 BAD: Casting bypasses the type system entirely. The snippet's
// `unchecked_sql` is `UntrustedSqlFragment` for a reason — never cast it.
function UnsafeSnippetRunner({ snippet }: { snippet: Snippet }) {
const { mutate: execute } = useExecuteSqlMutation()
useEffect(() => {
execute({ sql: snippet.content.unchecked_sql as SafeSqlFragment })
}, [snippet])
}// ✅ GOOD: Snippet content is only promoted to SafeSqlFragment inside an event
// handler, after the user clicks Run. The user has seen the SQL in the editor
// and explicitly chosen to execute it.
import { acceptUntrustedSql } from '@supabase/pg-meta'
function SnippetRunner({ snippet }: { snippet: Snippet }) {
const { mutate: execute } = useExecuteSqlMutation()
const handleRun = () => {
execute({ sql: acceptUntrustedSql(snippet.content.unchecked_sql) })
}
return (
<>
<SnippetEditor snippet={snippet} />
<button onClick={handleRun}>Run</button>
</>
)
}The same security model applies to analytics queries, which target BigQuery
or ClickHouse via the
/platform/projects/{ref}/analytics/endpoints/logs.all{,.otel} endpoints.
Filter keys and values from URL parameters and UI inputs are spliced into SQL
that runs against the project's logs, so the same injection risk exists.
Analytics SQL uses its own SafeLogSqlFragment brand
(apps/studio/data/logs/safe-analytics-sql.ts), intentionally disjoint
from the pg-meta SafeSqlFragment brand. The brands are kept separate because
escape semantics differ — Postgres-safe E'…' strings, ::jsonb casts, and
double-quoted identifiers are unsafe for BigQuery and/or ClickHouse, and vice
versa. Crossing the brands would silently emit unsafe SQL.
The wire boundary is executeAnalyticsSql in
apps/studio/data/logs/execute-analytics-sql.ts, analogous to pg-meta's
executeSql; it accepts only SafeLogSqlFragment, and an eslint
no-restricted-syntax rule in apps/studio/eslint.config.cjs blocks direct
post()/get() calls to the logs.all endpoints from any other file.
Build fragments with the helpers in safe-analytics-sql.ts:
safeSql — template tag that only accepts SafeLogSqlFragment
interpolations; plain strings and Postgres SafeSqlFragments are rejected at
compile time.analyticsLiteral(value) — sanitizes string/number/boolean literals.quotedIdent(name) — validates and backtick-quotes dotted identifiers.keyword(value, allowed) — resolves a value against an allow-list of
fragments (e.g. AND/OR); never returns the raw input.joinSqlFragments(fragments, separator) — composes already-branded
fragments.import { executeAnalyticsSql } from '@/data/logs/execute-analytics-sql'
import { analyticsLiteral, quotedIdent, safeSql } from '@/data/logs/safe-analytics-sql'
// ✅ GOOD: every interpolation is sanitized.
const sql = safeSql`
SELECT timestamp, event_message
FROM ${quotedIdent(table)}
WHERE id = ${analyticsLiteral(id)}
`
await executeAnalyticsSql({ projectRef, endpoint, sql, iso_timestamp_start, iso_timestamp_end })// 🛑 BAD: raw string interpolation. This fails to type-check at the
// executeAnalyticsSql boundary because the result is `string`, not
// `SafeLogSqlFragment`.
const sql = `SELECT * FROM ${table} WHERE id = '${id}'`
await executeAnalyticsSql({ projectRef, endpoint, sql, iso_timestamp_start, iso_timestamp_end })The only path that runs SQL not built from these helpers is user-authored
editor text: untrustedLogSql(text) marks it UntrustedLogSqlFragment
(displayable and storable, never executable), and acceptUntrustedLogsSql
promotes it to SafeLogSqlFragment. That promotion is a security boundary
— call it only from a run gesture (Run button click, Cmd+Enter) or an
approval-gated tool call (the AI notebook tools). Never from render,
useEffect, or any automatic path. The notebook persist path also promotes
cells because the writable notebook type requires the safe brand; that is
storage typing, not execution approval, and is not precedent for promoting
anywhere else. The same rule as acceptUntrustedSql on the Postgres side.
Endpoint selection, the OTEL query builders, and the rest of the Studio
wiring live in the clickhouse-logs-queries skill
(references/codebase-integration.md).
© supabase, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/safe-sql-execution of supabase/supabase.
Open the folder on GitHubat commit 26c838a
Safe SQL Execution next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Safe SQL Execution this skillsupabase/supabase | 111k | — | ~4.2k | Automated safety check: Pass | Apache-2.0 | |
| Stash Postgrescipherstash/stack | 157 | — | ~6.3k | Automated safety check: Pass | MIT | |
| Database FundamentalsDanielPodolsky/ownyourcode | 290 | 1 repos | ~1.6k | Automated safety check: Pass | MIT | |
| Golang Databaseunxed/f4 | 241 | 2 repos | ~2.9k | Automated safety check: Pass | MIT | |
| Srtd CLIt1mmen/srtd | 105 | — | ~360 | Automated safety check: Pass | MIT | |
| Drizzle Ormgrowupanand/ConvoForm | 101 | 1 repos | ~2.7k | Automated safety check: Pass | Apache-2.0 |
cipherstash/stack
Query EQL v3 encrypted columns from hand-written Postgres SQL over pg (node-postgres) or postgres (postgres-js) — no ORM.
DanielPodolsky/ownyourcode
Reviews schema design, SQL queries, ORM patterns. An agent skill from DanielPodolsky/ownyourcode.
unxed/f4
Comprehensive guide for Go database access — parameterized queries, struct scanning, NULLable columns, transactions, isolation levels, SELECT FOR UPDATE, connection pool, batch processing, context…
t1mmen/srtd
This skill should be used when the user mentions "srtd", "sql templates", "migrations-templates", "live reload sql", "supabase functions", when working with files in supabase/migrations-templates/…
growupanand/ConvoForm
Type-safe SQL ORM for TypeScript with zero runtime overhead. An agent skill from growupanand/ConvoForm.
ReJeCtAll/ExpertTeam-Codex
数据库优化专家入口。用于 Codex CLI 的 $expert-database 调用. An agent skill from ReJeCtAll/ExpertTeam-Codex.
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
supabase/supabase
Write, review, and migrate Supabase logs queries against the ClickHouse-backed logs table (the logs.all.otel analytics endpoint).
supabase/supabase
Review Supabase docs changes locally in your supabase/supabase checkout — either an open PR (triage, classify, verify) or your own branch before opening a PR (local self-review).
supabase/supabase
Vitest API and config reference (Jest-compatible) — mocking with vi., spies, fake timers, coverage configuration, fixtures, snapshots, and test filtering.
supabase/supabase
Write and run Playwright E2E tests for Supabase Studio (e2e/studio).
supabase/supabase
Error display and troubleshooting pattern for Supabase Studio.
Works with
Categories
A skill your agent uses whenever code will build, return, fetch, or execute SQL that runs against a user's real Postgres database — even when the request reads like an ordinary feature or bug fix…. Safe SQL Execution is an agent skill from supabase/supabase, published by the product's own GitHub organization.
Safe SQL Execution fits situations like: code will build; execute SQL that runs against a users real Postgres database — even when the request reads like an ordinary feature; bug fix and never says security; safeSqlFragment. This covers: writing.
Run `npx skills add supabase/supabase --skill safe-sql-execution -a claude-code`. Or copy the skill folder (.agents/skills/safe-sql-execution in supabase/supabase) into .claude/skills/safe-sql-execution in your project. Claude Code loads it when a task matches its description.
Run `npx skills add supabase/supabase --skill safe-sql-execution -a codex`. Or copy the skill folder (.agents/skills/safe-sql-execution in supabase/supabase) into .agents/skills/safe-sql-execution in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add supabase/supabase --skill safe-sql-execution -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/safe-sql-execution, .gemini/skills/safe-sql-execution, .github/skills/safe-sql-execution and .opencode/skills/safe-sql-execution in your project.
SKILL.md names no scripts, command-line tools or credentials: Safe SQL Execution is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Safe SQL Execution is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.2k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Safe SQL Execution: Stash Postgres (cipherstash/stack, 157 stars), Database Fundamentals (DanielPodolsky/ownyourcode, 290 stars), Golang Database (unxed/f4, 241 stars) and Srtd CLI (t1mmen/srtd, 105 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
supabase (a GitHub organization, an official publisher) maintains it in supabase/supabase, which has 111,222 GitHub stars. The repository holds 22 skills in this directory. The repository was last updated on October 8, 2026.
Source: supabase/supabase on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.