diff --git a/CLAUDE-POSTGRES.md b/CLAUDE-POSTGRES.md new file mode 100644 index 0000000..03b84b3 --- /dev/null +++ b/CLAUDE-POSTGRES.md @@ -0,0 +1,38 @@ +# General PostgreSQL Guidance + +Guidance in this file is about **PostgreSQL itself** rather than about pgxntool -- it +applies just as much in a project that has never heard of pgxntool. `CLAUDE.md`, next to +this file, covers pgxntool proper. + +As with `CLAUDE.md`, an extension project's own CLAUDE.md and instructions take +precedence over anything here. + +The human-facing version of this material is `POSTGRES-NOTES.asc`. + +## Never Mention `trusted` Without `superuser = false` and the Security Caveat + +Whenever you bring up the `trusted` control-file parameter -- in code, a comment, a +document, a commit message, a PR, or a chat reply -- you MUST in the same breath also: + +1. Offer `superuser = false` as the alternative, and +2. State that `trusted = true` carries security consequences, pointing at PostgreSQL's + [Security Considerations for Extensions](https://www.postgresql.org/docs/current/extend-extensions.html#EXTEND-EXTENSIONS-SECURITY) + rather than reassuring the reader yourself. + +The rule is one-directional: mentioning `superuser = false` on its own is fine. It is +specifically `trusted` that must never appear unaccompanied. + +**Why**: `trusted = true` is the answer that comes to mind fastest for "how do I let a +non-superuser install this?", so raising it alone reads as a recommendation. It isn't a +free switch -- it runs the install script as the bootstrap superuser on behalf of an +unprivileged caller, which turns any flaw in that script into privilege escalation. +`superuser = false` solves the same problem while granting nothing: the caller simply +needs the privileges the script actually uses. When the extension doesn't require +superuser-only capabilities, that's the better suggestion. + +See `POSTGRES-NOTES.asc` for the user-facing explanation of both parameters. + +## Metrics and Estimates + +Never produce any kind of metrics or estimates unless you have data to back them up. If +you do have data you MUST reference it. diff --git a/CLAUDE.md b/CLAUDE.md index 65e3bf7..17ca775 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,6 +30,16 @@ development must be done from the **pgxntool-test** repository, not from here. S Any agent working in an extension project should always defer to that project's own CLAUDE.md and instructions over anything stated here. +Guidance that is about PostgreSQL itself rather than about pgxntool lives in +`CLAUDE-POSTGRES.md` instead, so that this file stays about pgxntool. + +## Read `CLAUDE-POSTGRES.md` + +**`CLAUDE-POSTGRES.md` (next to this file) contains rules you must follow.** The `@` line +below imports it where that is supported; read the file directly if it did not. + +@CLAUDE-POSTGRES.md + ## Git Commit Guidelines **IMPORTANT**: When creating commit messages, do not attribute commits to yourself (Claude). Commit messages should reflect the work being done without AI attribution in the message body. The standard Co-Authored-By trailer is acceptable. @@ -288,5 +298,4 @@ may lack such a header. ## Related Repositories -- **pgxntool-test** - Test harness for validating pgxntool functionality: https://github.com/Postgres-Extensions/pgxntool-test -- Never produce any kind of metrics or estimates unless you have data to back them up. If you do have data you MUST reference it. \ No newline at end of file +- **pgxntool-test** - Test harness for validating pgxntool functionality: https://github.com/Postgres-Extensions/pgxntool-test \ No newline at end of file diff --git a/POSTGRES-NOTES.asc b/POSTGRES-NOTES.asc new file mode 100644 index 0000000..ea1001c --- /dev/null +++ b/POSTGRES-NOTES.asc @@ -0,0 +1,43 @@ += General PostgreSQL Notes +Not about PGXNtool +:sectlinks: +:sectanchors: +:toc: + +This file collects guidance about *PostgreSQL itself* rather than about PGXNtool. It +lives here because these questions come up constantly while writing an extension, and +PGXNtool's docs are where extension authors already are. Nothing here describes +PGXNtool behavior, and nothing PGXNtool does depends on it. + +For PGXNtool's own documentation, see link:README.asc[README.asc]. + +== Who Can Install Your Extension: `superuser` and `trusted` + +By default only a superuser can run `CREATE EXTENSION` or `ALTER EXTENSION ... UPDATE` +for your extension. Two `.control` file parameters change that. + +`superuser = false`:: +Removes the superuser requirement outright. The install/update script then runs as the +user who invoked `CREATE EXTENSION`, so that user must already hold every privilege the +script needs -- nothing is granted implicitly. + +`trusted = true`:: +Lets any non-superuser with `CREATE` privilege on the database install the extension, +but runs the install/update script as the *bootstrap superuser* instead of as the +caller. It is only consulted when `superuser` is true (the default), and requires +PostgreSQL 13 or later. + +WARNING: `trusted = true` has real security consequences. Because the script runs with +superuser rights on behalf of an unprivileged caller, any weakness in it becomes a +privilege-escalation path, and writing a trusted extension's SQL safely takes deliberate +effort. Read PostgreSQL's own +https://www.postgresql.org/docs/current/extend-extensions.html#EXTEND-EXTENSIONS-SECURITY[Security +Considerations for Extensions] before setting it. + +If your extension doesn't need superuser-only capabilities, `superuser = false` is +usually the better of the two: it grants nothing, it merely stops requiring superuser. + +PostgreSQL's reference documentation for both parameters: +https://www.postgresql.org/docs/current/extend-extensions.html#EXTEND-EXTENSIONS-FILES-SUPERUSER[`superuser`] +and +https://www.postgresql.org/docs/current/extend-extensions.html#EXTEND-EXTENSIONS-FILES-TRUSTED[`trusted`]. diff --git a/README.asc b/README.asc index 45c4b59..ce69161 100644 --- a/README.asc +++ b/README.asc @@ -736,6 +736,13 @@ Default: `yes`. Sub-check of check-stale-expected, independent of `PGXNTOOL_ENAB Default: unset (PGXS is included normally). Skips including PGXS (`$(PGXS)`) entirely. This is only for advanced scenarios where you need to manage the PGXS include yourself; most projects should never set this. +== General PostgreSQL Notes + +link:POSTGRES-NOTES.asc[POSTGRES-NOTES.asc] collects guidance about PostgreSQL itself +rather than about PGXNtool -- things that come up constantly while writing an extension +but that PGXNtool has no part in. It currently covers which `.control` file parameters +(`superuser`, `trusted`) control who is allowed to install your extension. + == Copyright Copyright (c) 2026 Jim Nasby