@evertonferreira96/agents 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/.claude/agents/api.md +45 -0
  2. package/.claude/agents/app.md +41 -0
  3. package/.claude/agents/architect.md +49 -0
  4. package/.claude/agents/infra.md +27 -0
  5. package/.claude/agents/product.md +58 -0
  6. package/.claude/agents/quick.md +33 -0
  7. package/.claude/agents/security.md +39 -0
  8. package/.claude/agents/ui.md +54 -0
  9. package/.claude/agents/verifier.md +56 -0
  10. package/.claude/agents/web.md +41 -0
  11. package/.claude/hooks/config-update-check.mjs +14 -0
  12. package/.claude/hooks/context-budget.mjs +51 -0
  13. package/.claude/hooks/graphify-update.sh +16 -0
  14. package/.claude/hooks/guard-bash.sh +64 -0
  15. package/.claude/hooks/orchestrator-guard.sh +49 -0
  16. package/.claude/hooks/post-compact.sh +26 -0
  17. package/.claude/hooks/readonly-guard.sh +54 -0
  18. package/.claude/hooks/stop-verify.sh +52 -0
  19. package/.claude/rules/api.md +21 -0
  20. package/.claude/rules/db.md +9 -0
  21. package/.claude/rules/delivery-diagram.md +16 -0
  22. package/.claude/rules/git-workflow.md +34 -0
  23. package/.claude/rules/graphify.md +3 -0
  24. package/.claude/rules/mobile.md +22 -0
  25. package/.claude/rules/tickets.md +9 -0
  26. package/.claude/rules/ui.md +14 -0
  27. package/.claude/rules/web.md +27 -0
  28. package/.claude/settings.json +114 -0
  29. package/.claude/skills/animate/RECIPES.md +324 -0
  30. package/.claude/skills/animate/SKILL.md +208 -0
  31. package/.claude/skills/animate/agents/openai.yaml +5 -0
  32. package/.claude/skills/animate-expo/RECIPES.md +385 -0
  33. package/.claude/skills/animate-expo/SKILL.md +264 -0
  34. package/.claude/skills/animate-expo/agents/openai.yaml +5 -0
  35. package/.claude/skills/animation-performance/SKILL.md +223 -0
  36. package/.claude/skills/animation-performance/agents/openai.yaml +5 -0
  37. package/.claude/skills/apple-design/SKILL.md +291 -0
  38. package/.claude/skills/apple-design/agents/openai.yaml +5 -0
  39. package/.claude/skills/arch-api/SKILL.md +291 -0
  40. package/.claude/skills/arch-api/agents/openai.yaml +3 -0
  41. package/.claude/skills/arch-api/references/common.md +174 -0
  42. package/.claude/skills/arch-api/references/contract.md +289 -0
  43. package/.claude/skills/arch-api/references/domain.md +301 -0
  44. package/.claude/skills/arch-api/references/endpoints.md +184 -0
  45. package/.claude/skills/arch-api/references/review.md +228 -0
  46. package/.claude/skills/arch-api/references/security.md +151 -0
  47. package/.claude/skills/arch-app/SKILL.md +278 -0
  48. package/.claude/skills/arch-app/agents/openai.yaml +3 -0
  49. package/.claude/skills/arch-app/references/navigation-session.md +257 -0
  50. package/.claude/skills/arch-app/references/review.md +155 -0
  51. package/.claude/skills/arch-app/references/screens.md +214 -0
  52. package/.claude/skills/arch-app/references/services.md +301 -0
  53. package/.claude/skills/arch-app/references/ui-mobile.md +124 -0
  54. package/.claude/skills/arch-db/SKILL.md +181 -0
  55. package/.claude/skills/arch-db/agents/openai.yaml +3 -0
  56. package/.claude/skills/arch-db/references/indexes-queries.md +251 -0
  57. package/.claude/skills/arch-db/references/migrations.md +191 -0
  58. package/.claude/skills/arch-db/references/modeling.md +214 -0
  59. package/.claude/skills/arch-db/references/mysql.md +262 -0
  60. package/.claude/skills/arch-db/references/pooling-ops.md +112 -0
  61. package/.claude/skills/arch-db/references/review.md +143 -0
  62. package/.claude/skills/arch-db/references/transactions-locks.md +141 -0
  63. package/.claude/skills/arch-web/SKILL.md +307 -0
  64. package/.claude/skills/arch-web/agents/openai.yaml +3 -0
  65. package/.claude/skills/arch-web/references/auth-session-env.md +165 -0
  66. package/.claude/skills/arch-web/references/blocks.md +198 -0
  67. package/.claude/skills/arch-web/references/cache.md +124 -0
  68. package/.claude/skills/arch-web/references/review.md +142 -0
  69. package/.claude/skills/arch-web/references/services.md +297 -0
  70. package/.claude/skills/arch-web/references/tests.md +159 -0
  71. package/.claude/skills/arch-web/references/ui-forms.md +143 -0
  72. package/.claude/skills/break-ui/CATALOG.md +135 -0
  73. package/.claude/skills/break-ui/SKILL.md +176 -0
  74. package/.claude/skills/break-ui/agents/openai.yaml +5 -0
  75. package/.claude/skills/brief/SKILL.md +91 -0
  76. package/.claude/skills/brief/agents/openai.yaml +3 -0
  77. package/.claude/skills/diagnosing-bugs/SKILL.md +138 -0
  78. package/.claude/skills/diagnosing-bugs/agents/openai.yaml +3 -0
  79. package/.claude/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
  80. package/.claude/skills/emil-design-eng/SKILL.md +675 -0
  81. package/.claude/skills/emil-design-eng/agents/openai.yaml +5 -0
  82. package/.claude/skills/find-animation-opportunities/SKILL.md +141 -0
  83. package/.claude/skills/find-animation-opportunities/agents/openai.yaml +5 -0
  84. package/.claude/skills/graphify/.graphify_version +1 -0
  85. package/.claude/skills/graphify/SKILL.md +742 -0
  86. package/.claude/skills/graphify/agents/openai.yaml +3 -0
  87. package/.claude/skills/graphify/references/add-watch.md +56 -0
  88. package/.claude/skills/graphify/references/exports.md +91 -0
  89. package/.claude/skills/graphify/references/extraction-spec.md +70 -0
  90. package/.claude/skills/graphify/references/github-and-merge.md +46 -0
  91. package/.claude/skills/graphify/references/hooks.md +33 -0
  92. package/.claude/skills/graphify/references/query.md +317 -0
  93. package/.claude/skills/graphify/references/transcribe.md +52 -0
  94. package/.claude/skills/graphify/references/update.md +221 -0
  95. package/.claude/skills/grill-me/SKILL.md +7 -0
  96. package/.claude/skills/grill-me/agents/openai.yaml +5 -0
  97. package/.claude/skills/grill-with-docs/SKILL.md +64 -0
  98. package/.claude/skills/grill-with-docs/agents/openai.yaml +5 -0
  99. package/.claude/skills/grilling/SKILL.md +30 -0
  100. package/.claude/skills/grilling/agents/openai.yaml +3 -0
  101. package/.claude/skills/handoff/SKILL.md +28 -0
  102. package/.claude/skills/handoff/agents/openai.yaml +5 -0
  103. package/.claude/skills/impeccable/SKILL.md +89 -0
  104. package/.claude/skills/impeccable/agents/openai.yaml +5 -0
  105. package/.claude/skills/impeccable/reference/adapt.md +318 -0
  106. package/.claude/skills/impeccable/reference/adapt.native.md +58 -0
  107. package/.claude/skills/impeccable/reference/android.md +46 -0
  108. package/.claude/skills/impeccable/reference/animate.md +89 -0
  109. package/.claude/skills/impeccable/reference/audit.md +137 -0
  110. package/.claude/skills/impeccable/reference/audit.native.md +139 -0
  111. package/.claude/skills/impeccable/reference/bolder.md +33 -0
  112. package/.claude/skills/impeccable/reference/clarify.md +94 -0
  113. package/.claude/skills/impeccable/reference/colorize.md +86 -0
  114. package/.claude/skills/impeccable/reference/component-review.md +63 -0
  115. package/.claude/skills/impeccable/reference/craft-floor.md +44 -0
  116. package/.claude/skills/impeccable/reference/craft.md +5 -0
  117. package/.claude/skills/impeccable/reference/critique.md +809 -0
  118. package/.claude/skills/impeccable/reference/degraded/asset-producer.md +42 -0
  119. package/.claude/skills/impeccable/reference/degraded/documenter.md +24 -0
  120. package/.claude/skills/impeccable/reference/degraded/finish-reviewer.md +38 -0
  121. package/.claude/skills/impeccable/reference/degraded/manual-edit-applier.md +92 -0
  122. package/.claude/skills/impeccable/reference/delight.md +70 -0
  123. package/.claude/skills/impeccable/reference/distill.md +111 -0
  124. package/.claude/skills/impeccable/reference/doctor.md +54 -0
  125. package/.claude/skills/impeccable/reference/document.md +416 -0
  126. package/.claude/skills/impeccable/reference/extract.md +69 -0
  127. package/.claude/skills/impeccable/reference/generate.md +101 -0
  128. package/.claude/skills/impeccable/reference/harden.md +345 -0
  129. package/.claude/skills/impeccable/reference/hooks.md +113 -0
  130. package/.claude/skills/impeccable/reference/init.md +131 -0
  131. package/.claude/skills/impeccable/reference/ios.md +51 -0
  132. package/.claude/skills/impeccable/reference/layout.md +84 -0
  133. package/.claude/skills/impeccable/reference/live-setup.md +104 -0
  134. package/.claude/skills/impeccable/reference/live.md +325 -0
  135. package/.claude/skills/impeccable/reference/mode-operate.md +21 -0
  136. package/.claude/skills/impeccable/reference/mode-persuade.md +19 -0
  137. package/.claude/skills/impeccable/reference/mode-read.md +21 -0
  138. package/.claude/skills/impeccable/reference/new-work.md +154 -0
  139. package/.claude/skills/impeccable/reference/onboard.md +234 -0
  140. package/.claude/skills/impeccable/reference/operate.md +61 -0
  141. package/.claude/skills/impeccable/reference/optimize.md +258 -0
  142. package/.claude/skills/impeccable/reference/overdrive.md +127 -0
  143. package/.claude/skills/impeccable/reference/polish.md +105 -0
  144. package/.claude/skills/impeccable/reference/quieter.md +99 -0
  145. package/.claude/skills/impeccable/reference/region-map.md +26 -0
  146. package/.claude/skills/impeccable/reference/routing.md +24 -0
  147. package/.claude/skills/impeccable/reference/shape.md +59 -0
  148. package/.claude/skills/impeccable/reference/typeset.md +80 -0
  149. package/.claude/skills/impeccable/reference/visualize.md +47 -0
  150. package/.claude/skills/impeccable/scripts/VERSION +1 -0
  151. package/.claude/skills/impeccable/scripts/command-metadata.json +98 -0
  152. package/.claude/skills/impeccable/scripts/data/font-index-failures.json +121 -0
  153. package/.claude/skills/impeccable/scripts/data/font-index.json +1 -0
  154. package/.claude/skills/impeccable/scripts/impeccable +206 -0
  155. package/.claude/skills/impeccable/scripts/impeccable.cmd +214 -0
  156. package/.claude/skills/impeccable/scripts/live-browser-dom.js +281 -0
  157. package/.claude/skills/impeccable/scripts/live-browser-ignores.js +242 -0
  158. package/.claude/skills/impeccable/scripts/live-browser-session.js +148 -0
  159. package/.claude/skills/impeccable/scripts/live-browser.js +13532 -0
  160. package/.claude/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  161. package/.claude/skills/improve-animations/AUDIT.md +115 -0
  162. package/.claude/skills/improve-animations/PLAN-TEMPLATE.md +73 -0
  163. package/.claude/skills/improve-animations/SKILL.md +110 -0
  164. package/.claude/skills/improve-animations/agents/openai.yaml +5 -0
  165. package/.claude/skills/mobile-native/SKILL.md +311 -0
  166. package/.claude/skills/mobile-native/agents/openai.yaml +3 -0
  167. package/.claude/skills/orchestrate/SKILL.md +181 -0
  168. package/.claude/skills/orchestrate/agents/openai.yaml +3 -0
  169. package/.claude/skills/pick-ui-library/SKILL.md +85 -0
  170. package/.claude/skills/pick-ui-library/agents/openai.yaml +5 -0
  171. package/.claude/skills/ponytail/SKILL.md +52 -0
  172. package/.claude/skills/ponytail/agents/openai.yaml +3 -0
  173. package/.claude/skills/ponytail-audit/SKILL.md +103 -0
  174. package/.claude/skills/ponytail-audit/agents/openai.yaml +3 -0
  175. package/.claude/skills/ponytail-debt/SKILL.md +44 -0
  176. package/.claude/skills/ponytail-debt/agents/openai.yaml +3 -0
  177. package/.claude/skills/ponytail-review/SKILL.md +101 -0
  178. package/.claude/skills/ponytail-review/agents/openai.yaml +3 -0
  179. package/.claude/skills/postgres-best-practices/SKILL.md +42 -0
  180. package/.claude/skills/postgres-best-practices/agents/openai.yaml +3 -0
  181. package/.claude/skills/postgres-best-practices/references/backup-restore.md +372 -0
  182. package/.claude/skills/postgres-best-practices/references/bulk-loading.md +315 -0
  183. package/.claude/skills/postgres-best-practices/references/connection-pooling.md +310 -0
  184. package/.claude/skills/postgres-best-practices/references/hot-standby.md +221 -0
  185. package/.claude/skills/postgres-best-practices/references/indexing.md +318 -0
  186. package/.claude/skills/postgres-best-practices/references/logical-replication.md +610 -0
  187. package/.claude/skills/postgres-best-practices/references/major-version-upgrades.md +334 -0
  188. package/.claude/skills/postgres-best-practices/references/performance-diagnostics.md +553 -0
  189. package/.claude/skills/postgres-best-practices/references/query-optimization.md +294 -0
  190. package/.claude/skills/postgres-best-practices/references/query-patterns.md +566 -0
  191. package/.claude/skills/postgres-best-practices/references/schema-design.md +362 -0
  192. package/.claude/skills/postgres-best-practices/references/security-roles.md +489 -0
  193. package/.claude/skills/postgres-best-practices/references/transaction-isolation.md +344 -0
  194. package/.claude/skills/project-docs/SKILL.md +330 -0
  195. package/.claude/skills/project-docs/agents/openai.yaml +3 -0
  196. package/.claude/skills/prototype/PICKER.md +197 -0
  197. package/.claude/skills/prototype/SKILL.md +98 -0
  198. package/.claude/skills/prototype/agents/openai.yaml +5 -0
  199. package/.claude/skills/retro/SKILL.md +43 -0
  200. package/.claude/skills/retro/agents/openai.yaml +5 -0
  201. package/.claude/skills/review/SKILL.md +74 -0
  202. package/.claude/skills/review/agents/openai.yaml +3 -0
  203. package/.claude/skills/review/references/smells.md +23 -0
  204. package/.claude/skills/review-animations/SKILL.md +120 -0
  205. package/.claude/skills/review-animations/STANDARDS.md +187 -0
  206. package/.claude/skills/review-animations/agents/openai.yaml +5 -0
  207. package/.claude/skills/tdd/SKILL.md +38 -0
  208. package/.claude/skills/tdd/agents/openai.yaml +3 -0
  209. package/.claude/skills/tdd/mocking.md +59 -0
  210. package/.claude/skills/tdd/tests.md +77 -0
  211. package/.claude/skills/triage/SKILL.md +58 -0
  212. package/.claude/skills/triage/agents/openai.yaml +3 -0
  213. package/.claude/skills/ui-ux-pro-max/SKILL.md +378 -0
  214. package/.claude/skills/ui-ux-pro-max/agents/openai.yaml +5 -0
  215. package/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -0
  216. package/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -0
  217. package/.claude/skills/ui-ux-pro-max/data/icons.csv +101 -0
  218. package/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -0
  219. package/.claude/skills/ui-ux-pro-max/data/products.csv +97 -0
  220. package/.claude/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  221. package/.claude/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  222. package/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  223. package/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  224. package/.claude/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  225. package/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  226. package/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  227. package/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  228. package/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  229. package/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  230. package/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  231. package/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  232. package/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  233. package/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  234. package/.claude/skills/ui-ux-pro-max/data/styles.csv +68 -0
  235. package/.claude/skills/ui-ux-pro-max/data/typography.csv +58 -0
  236. package/.claude/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  237. package/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  238. package/.claude/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  239. package/.claude/skills/ui-ux-pro-max/scripts/core.py +253 -0
  240. package/.claude/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  241. package/.claude/skills/ui-ux-pro-max/scripts/search.py +114 -0
  242. package/.claude/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
  243. package/.claude/skills/writing-for-agents/SKILL.md +81 -0
  244. package/.claude/skills/writing-for-agents/agents/openai.yaml +3 -0
  245. package/.worktreeinclude +3 -0
  246. package/AGENTS.md +44 -0
  247. package/README.md +14 -2
  248. package/VERSION +1 -0
  249. package/bin/agents.mjs +45 -0
  250. package/docs/adr/README.md +31 -0
  251. package/docs/brief-template.md +3 -0
  252. package/docs/plans/README.md +73 -0
  253. package/package.json +46 -4
  254. package/scripts/bootstrap.mjs +188 -0
  255. package/scripts/check-catalog.mjs +43 -0
  256. package/scripts/skills-update.mjs +51 -0
  257. package/skills-lock.json +269 -0
  258. package/templates/CLAUDE.project.md +41 -0
@@ -0,0 +1,489 @@
1
+ # Security & Roles Reference
2
+
3
+ ## Contents
4
+ - Role management
5
+ - Privilege system
6
+ - Schema-based access control
7
+ - Row-Level Security (RLS)
8
+ - pg_hba.conf authentication
9
+ - Password policies and authentication methods
10
+ - Security functions and best practices
11
+
12
+ ## Role Management
13
+
14
+ PostgreSQL uses **roles** for both users and groups. A role with `LOGIN` is a user; a role without is a group.
15
+
16
+ ### Creating Roles
17
+
18
+ ```sql
19
+ -- User role (can log in)
20
+ CREATE ROLE app_user WITH LOGIN PASSWORD 'strong_password_here';
21
+
22
+ -- Group role (cannot log in, used for privilege grouping)
23
+ CREATE ROLE readonly;
24
+ CREATE ROLE readwrite;
25
+ CREATE ROLE admin;
26
+
27
+ -- Role with specific attributes
28
+ CREATE ROLE backup_user WITH LOGIN REPLICATION PASSWORD '...';
29
+ CREATE ROLE migrator WITH LOGIN CREATEDB PASSWORD '...';
30
+ ```
31
+
32
+ ### Role Attributes
33
+
34
+ | Attribute | Meaning |
35
+ |-----------|---------|
36
+ | `LOGIN` | Can connect to the database |
37
+ | `SUPERUSER` | Bypasses all permission checks (dangerous) |
38
+ | `CREATEDB` | Can create databases |
39
+ | `CREATEROLE` | Can create/alter/drop other roles |
40
+ | `REPLICATION` | Can initiate streaming replication |
41
+ | `BYPASSRLS` | Bypasses Row-Level Security policies |
42
+ | `INHERIT` | Automatically inherits privileges of member roles (default) |
43
+ | `CONNECTION LIMIT n` | Max concurrent connections for this role |
44
+ | `VALID UNTIL 'timestamp'` | Password expiration |
45
+
46
+ ```sql
47
+ -- Modify attributes
48
+ ALTER ROLE app_user WITH CONNECTION LIMIT 10;
49
+ ALTER ROLE temp_user VALID UNTIL '2025-01-01';
50
+ ALTER ROLE app_user WITH PASSWORD 'new_password';
51
+
52
+ -- Inspect roles
53
+ SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin,
54
+ rolreplication, rolbypassrls, rolconnlimit, rolvaliduntil
55
+ FROM pg_roles
56
+ WHERE rolname NOT LIKE 'pg_%'
57
+ ORDER BY rolname;
58
+ ```
59
+
60
+ ### Group Membership
61
+
62
+ ```sql
63
+ -- Add a user to a group
64
+ GRANT readonly TO app_user;
65
+ GRANT readwrite TO app_user;
66
+
67
+ -- Remove membership
68
+ REVOKE readwrite FROM app_user;
69
+
70
+ -- Check memberships
71
+ SELECT
72
+ r.rolname AS role,
73
+ m.rolname AS member
74
+ FROM pg_auth_members am
75
+ JOIN pg_roles r ON r.oid = am.roleid
76
+ JOIN pg_roles m ON m.oid = am.member
77
+ ORDER BY r.rolname, m.rolname;
78
+ ```
79
+
80
+ ### Predefined Roles
81
+
82
+ PostgreSQL provides system-defined roles for common privileged capabilities. PostgreSQL 13 and earlier documentation called these "default roles"; PostgreSQL 14 renamed the category to "predefined roles." Individual roles were introduced in different releases.
83
+
84
+ | Role | Grants |
85
+ |------|--------|
86
+ | `pg_read_all_data` | SELECT on all tables, views, sequences in all schemas |
87
+ | `pg_write_all_data` | INSERT, UPDATE, DELETE on all tables, sequences in all schemas |
88
+ | `pg_read_all_settings` | Read all GUC settings (even superuser-only) |
89
+ | `pg_read_all_stats` | Read all pg_stat_* views |
90
+ | `pg_monitor` | Read monitoring views (`pg_stat_*`, `pg_locks`, etc.) |
91
+ | `pg_signal_backend` | Send signals to other backends (cancel/terminate) |
92
+ | `pg_checkpoint` (PG15+) | Run CHECKPOINT |
93
+ | `pg_maintain` (PG17+) | Run VACUUM, ANALYZE, REINDEX, CLUSTER, REFRESH MATERIALIZED VIEW, and LOCK TABLE on all relations |
94
+
95
+ ```sql
96
+ -- Give a monitoring role read access to all stats
97
+ GRANT pg_monitor TO monitoring_user;
98
+
99
+ -- Give an app role read access to all data without per-table grants
100
+ GRANT pg_read_all_data TO reporting_user;
101
+ ```
102
+
103
+ ## Privilege System
104
+
105
+ ### Object Privileges
106
+
107
+ ```sql
108
+ -- Grant on tables
109
+ GRANT SELECT ON orders TO readonly;
110
+ GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO readwrite;
111
+ GRANT ALL PRIVILEGES ON orders TO admin;
112
+
113
+ -- Grant on all tables in a schema
114
+ GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
115
+ GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO readwrite;
116
+
117
+ -- Grant on sequences (needed for INSERT with serial/identity columns)
118
+ GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO readwrite;
119
+
120
+ -- Grant on schema (required to access objects within it)
121
+ GRANT USAGE ON SCHEMA public TO readonly;
122
+ GRANT USAGE, CREATE ON SCHEMA public TO readwrite;
123
+ ```
124
+
125
+ ### Default Privileges
126
+
127
+ Set privileges that automatically apply to future objects:
128
+
129
+ ```sql
130
+ -- As the object owner or superuser:
131
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
132
+ GRANT SELECT ON TABLES TO readonly;
133
+
134
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
135
+ GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
136
+
137
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
138
+ GRANT USAGE ON SEQUENCES TO readwrite;
139
+
140
+ -- For objects created by a specific role:
141
+ ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA public
142
+ GRANT SELECT ON TABLES TO readonly;
143
+ ```
144
+
145
+ **Important**: Default privileges only affect objects created **after** the `ALTER DEFAULT PRIVILEGES` command. Existing objects need explicit `GRANT`.
146
+
147
+ ### Revoking Privileges
148
+
149
+ ```sql
150
+ -- Revoke specific privileges
151
+ REVOKE INSERT, UPDATE, DELETE ON orders FROM readonly;
152
+
153
+ -- Revoke all privileges
154
+ REVOKE ALL PRIVILEGES ON orders FROM some_role;
155
+
156
+ -- Revoke from public (default grant on new databases)
157
+ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
158
+ REVOKE ALL ON DATABASE mydb FROM PUBLIC;
159
+ ```
160
+
161
+ ### Inspecting Privileges
162
+
163
+ ```sql
164
+ -- Table privileges
165
+ SELECT
166
+ grantee,
167
+ table_schema,
168
+ table_name,
169
+ privilege_type
170
+ FROM information_schema.table_privileges
171
+ WHERE table_schema = 'public'
172
+ ORDER BY table_name, grantee;
173
+
174
+ -- Compact: privileges per table
175
+ SELECT
176
+ relname,
177
+ relacl -- array of 'grantee=privileges/grantor'
178
+ FROM pg_class
179
+ WHERE relkind = 'r' AND relnamespace = 'public'::regnamespace;
180
+
181
+ -- Function privileges
182
+ SELECT
183
+ routine_name,
184
+ grantee,
185
+ privilege_type
186
+ FROM information_schema.routine_privileges
187
+ WHERE routine_schema = 'public';
188
+ ```
189
+
190
+ ## Schema-Based Access Control
191
+
192
+ Use schemas to organize objects and control access:
193
+
194
+ ```sql
195
+ -- Create isolated schemas
196
+ CREATE SCHEMA app;
197
+ CREATE SCHEMA reporting;
198
+ CREATE SCHEMA staging;
199
+
200
+ -- Grant access per schema
201
+ GRANT USAGE ON SCHEMA app TO app_user;
202
+ GRANT USAGE ON SCHEMA reporting TO reporting_user;
203
+ GRANT USAGE ON SCHEMA staging TO etl_user;
204
+
205
+ -- Remove default public schema access
206
+ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
207
+ ```
208
+
209
+ ### Search Path Security
210
+
211
+ The `search_path` determines which schemas are searched for unqualified table names. A malicious `search_path` can redirect queries to attacker-controlled tables.
212
+
213
+ ```sql
214
+ -- Set a safe search path (explicit, no reliance on public)
215
+ ALTER ROLE app_user SET search_path = app, public;
216
+
217
+ -- For functions: use SECURITY DEFINER carefully
218
+ CREATE FUNCTION get_balance(account_id int) RETURNS numeric
219
+ SECURITY DEFINER
220
+ SET search_path = pg_catalog, pg_temp
221
+ AS $$
222
+ SELECT balance FROM app.accounts WHERE id = account_id;
223
+ $$ LANGUAGE sql;
224
+ ```
225
+
226
+ **Always give `SECURITY DEFINER` functions a fixed `search_path` containing only trusted schemas.** Explicitly list `pg_temp` last: if it is omitted, PostgreSQL searches the session's temporary schema first for relations and data types, which can allow temporary objects to shadow intended objects. When application objects are fully qualified, prefer `pg_catalog, pg_temp`; otherwise list only trusted application schemas followed by `pg_temp`.
227
+
228
+ ## Row-Level Security (RLS)
229
+
230
+ RLS adds per-row access control enforced by the database, not the application.
231
+
232
+ ### Basic Setup
233
+
234
+ ```sql
235
+ -- Enable RLS on a table
236
+ ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
237
+
238
+ -- Policy for tenant isolation
239
+ CREATE POLICY tenant_isolation ON orders
240
+ USING (tenant_id = current_setting('app.current_tenant')::int);
241
+
242
+ -- Test through a non-owner application role; table owners bypass RLS by default.
243
+ SET ROLE app_user;
244
+ SET app.current_tenant = '42';
245
+
246
+ -- All queries on orders now automatically filter by tenant_id = 42
247
+ SELECT * FROM orders; -- only sees tenant 42's orders
248
+ RESET ROLE;
249
+ ```
250
+
251
+ ### Policy Types
252
+
253
+ ```sql
254
+ -- SELECT policy (restrict which rows can be read)
255
+ CREATE POLICY read_own ON documents
256
+ FOR SELECT
257
+ USING (owner_id = current_setting('app.current_user_id')::bigint);
258
+
259
+ -- INSERT policy (restrict which rows can be inserted)
260
+ CREATE POLICY insert_own ON documents
261
+ FOR INSERT
262
+ WITH CHECK (owner_id = current_setting('app.current_user_id')::bigint);
263
+
264
+ -- UPDATE policy (restrict which rows can be updated, and what values are allowed)
265
+ CREATE POLICY update_own ON documents
266
+ FOR UPDATE
267
+ USING (owner_id = current_setting('app.current_user_id')::bigint) -- rows selectable for update
268
+ WITH CHECK (owner_id = current_setting('app.current_user_id')::bigint); -- required post-update value
269
+
270
+ -- DELETE policy
271
+ CREATE POLICY delete_own ON documents
272
+ FOR DELETE
273
+ USING (owner_id = current_setting('app.current_user_id')::bigint);
274
+
275
+ -- ALL (applies to all commands)
276
+ CREATE POLICY full_access ON documents
277
+ FOR ALL
278
+ USING (owner_id = current_setting('app.current_user_id')::bigint)
279
+ WITH CHECK (owner_id = current_setting('app.current_user_id')::bigint);
280
+ ```
281
+
282
+ ### Multiple Policies
283
+
284
+ Multiple policies on the same table are combined with OR (by default). Use `RESTRICTIVE` for AND:
285
+
286
+ ```sql
287
+ -- Permissive (default): combined with OR
288
+ CREATE POLICY see_active ON orders
289
+ USING (status = 'active');
290
+
291
+ CREATE POLICY see_own ON orders
292
+ USING (user_id = current_setting('app.current_user_id')::bigint);
293
+ -- User sees rows that are active OR owned by them
294
+
295
+ -- Restrictive: combined with AND (with permissive policies)
296
+ CREATE POLICY must_be_active ON orders AS RESTRICTIVE
297
+ USING (status != 'deleted');
298
+ -- Combined: (active OR own) AND not_deleted
299
+ ```
300
+
301
+ ### RLS Caveats
302
+
303
+ - **Table owner bypasses RLS** by default. Use `ALTER TABLE ... FORCE ROW LEVEL SECURITY` to apply RLS to the owner too.
304
+ - **Superusers and `BYPASSRLS` roles** bypass all RLS policies.
305
+ - **No policies = deny all** when RLS is enabled (except for table owner).
306
+ - **Performance**: RLS adds filter conditions to every query. Ensure the policy columns are indexed.
307
+ - **Leaky views**: Functions in RLS policies that are not `LEAKPROOF` could theoretically leak data via error messages or side channels. Use `LEAKPROOF` functions where possible.
308
+
309
+ ```sql
310
+ -- Force RLS on table owner
311
+ ALTER TABLE orders FORCE ROW LEVEL SECURITY;
312
+
313
+ -- Check which tables have RLS enabled
314
+ SELECT relname, relrowsecurity, relforcerowsecurity
315
+ FROM pg_class
316
+ WHERE relkind = 'r' AND relnamespace = 'public'::regnamespace;
317
+ ```
318
+
319
+ ## pg_hba.conf Authentication
320
+
321
+ `pg_hba.conf` controls who can connect, from where, and how they authenticate. Rules are evaluated top-to-bottom; first match wins.
322
+
323
+ ### Format
324
+
325
+ ```
326
+ # TYPE DATABASE USER ADDRESS METHOD
327
+ local all all scram-sha-256
328
+ host all all 127.0.0.1/32 scram-sha-256
329
+ host all all ::1/128 scram-sha-256
330
+ host mydb app_user 10.0.0.0/8 scram-sha-256
331
+ host all all 0.0.0.0/0 reject
332
+ ```
333
+
334
+ ### Authentication Methods
335
+
336
+ | Method | Security | Use case |
337
+ |--------|----------|----------|
338
+ | `scram-sha-256` | Strong | **Recommended default** — salted challenge-response |
339
+ | `md5` | Weak | Legacy — **deprecated in PG18** (emits warnings) |
340
+ | `cert` | Strong | Client certificate (mutual TLS) |
341
+ | `peer` | Strong | Local connections — maps OS user to PG role |
342
+ | `ident` | Moderate | TCP — maps OS user via ident server |
343
+ | `gss` | Strong | Kerberos/GSSAPI |
344
+ | `ldap` | Moderate | LDAP directory authentication |
345
+ | `trust` | None | **Never use in production** — no password required |
346
+ | `reject` | N/A | Explicitly deny connections |
347
+
348
+ ### Best Practices
349
+
350
+ ```
351
+ # 1. Use scram-sha-256 (not md5)
352
+ # 2. Be specific — don't use 'all' for database/user in production
353
+ # 3. Restrict by IP range
354
+ # 4. Put reject rules at the bottom as a catch-all
355
+ # 5. Use 'local peer' for admin access (no password over unix socket)
356
+
357
+ local all postgres peer
358
+ host mydb app_user 10.0.1.0/24 scram-sha-256
359
+ host replication repl_user 10.0.2.0/24 scram-sha-256
360
+ hostssl mydb all 0.0.0.0/0 scram-sha-256
361
+ host all all 0.0.0.0/0 reject
362
+ ```
363
+
364
+ After modifying `pg_hba.conf`, reload:
365
+
366
+ ```sql
367
+ SELECT pg_reload_conf();
368
+ -- or from CLI: pg_ctl reload
369
+ ```
370
+
371
+ ## Password Policies and Authentication
372
+
373
+ ### Enforce scram-sha-256
374
+
375
+ ```sql
376
+ -- In postgresql.conf:
377
+ -- password_encryption = scram-sha-256 (default in PG14+)
378
+
379
+ -- Verify
380
+ SHOW password_encryption;
381
+
382
+ -- Check which roles still use md5
383
+ SELECT rolname, rolpassword LIKE 'md5%' AS uses_md5
384
+ FROM pg_authid
385
+ WHERE rolcanlogin AND rolpassword IS NOT NULL;
386
+ ```
387
+
388
+ ### Password Expiration
389
+
390
+ ```sql
391
+ -- Set expiration on a role
392
+ ALTER ROLE app_user VALID UNTIL '2025-06-01';
393
+
394
+ -- Check expiration
395
+ SELECT rolname, rolvaliduntil
396
+ FROM pg_roles
397
+ WHERE rolvaliduntil IS NOT NULL;
398
+ ```
399
+
400
+ PostgreSQL does not enforce password complexity natively. Use `passwordcheck` module or application-level validation:
401
+
402
+ ```sql
403
+ -- In postgresql.conf:
404
+ -- shared_preload_libraries = 'passwordcheck'
405
+ -- Enforces minimum length and basic complexity
406
+ ```
407
+
408
+ ### SSL/TLS
409
+
410
+ ```sql
411
+ -- Check if SSL is enabled
412
+ SHOW ssl;
413
+
414
+ -- Check current connection's SSL status
415
+ SELECT ssl, version, cipher, bits
416
+ FROM pg_stat_ssl
417
+ WHERE pid = pg_backend_pid();
418
+
419
+ -- Require SSL for specific connections (in pg_hba.conf):
420
+ -- hostssl mydb all 0.0.0.0/0 scram-sha-256
421
+ -- hostnossl mydb all 0.0.0.0/0 reject
422
+ ```
423
+
424
+ ## Security Best Practices
425
+
426
+ ### Principle of Least Privilege
427
+
428
+ ```sql
429
+ -- 1. Revoke default public access
430
+ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
431
+ REVOKE ALL ON DATABASE mydb FROM PUBLIC;
432
+
433
+ -- 2. Create role groups with specific privileges
434
+ CREATE ROLE app_readonly;
435
+ GRANT USAGE ON SCHEMA public TO app_readonly;
436
+ GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_readonly;
437
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO app_readonly;
438
+
439
+ CREATE ROLE app_readwrite;
440
+ GRANT USAGE ON SCHEMA public TO app_readwrite;
441
+ GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_readwrite;
442
+ GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO app_readwrite;
443
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
444
+ GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_readwrite;
445
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
446
+ GRANT USAGE ON SEQUENCES TO app_readwrite;
447
+
448
+ -- 3. Assign users to groups
449
+ CREATE ROLE web_app WITH LOGIN PASSWORD '...';
450
+ GRANT app_readwrite TO web_app;
451
+
452
+ CREATE ROLE analyst WITH LOGIN PASSWORD '...';
453
+ GRANT app_readonly TO analyst;
454
+ ```
455
+
456
+ ### Audit Who Has Access
457
+
458
+ ```sql
459
+ -- All role memberships
460
+ SELECT
461
+ r.rolname AS group_role,
462
+ m.rolname AS member,
463
+ am.admin_option
464
+ FROM pg_auth_members am
465
+ JOIN pg_roles r ON r.oid = am.roleid
466
+ JOIN pg_roles m ON m.oid = am.member
467
+ ORDER BY r.rolname, m.rolname;
468
+
469
+ -- Roles with superuser
470
+ SELECT rolname FROM pg_roles WHERE rolsuper;
471
+
472
+ -- Roles with BYPASSRLS (can circumvent row-level security)
473
+ SELECT rolname FROM pg_roles WHERE rolbypassrls;
474
+
475
+ -- Roles that can create databases or roles
476
+ SELECT rolname, rolcreatedb, rolcreaterole
477
+ FROM pg_roles
478
+ WHERE rolcreatedb OR rolcreaterole;
479
+ ```
480
+
481
+ ### Avoid Common Security Mistakes
482
+
483
+ 1. **Never use `trust` authentication** in production (allows passwordless access)
484
+ 2. **Never run applications as superuser** — create dedicated roles with minimal privileges
485
+ 3. **Don't store passwords in connection strings** in code — use `.pgpass`, environment variables, or secret managers
486
+ 4. **Pin `search_path`** in `SECURITY DEFINER` functions
487
+ 5. **Enable SSL** for all non-local connections (`hostssl` in pg_hba.conf)
488
+ 6. **Audit superuser access** regularly — minimize the number of superuser roles
489
+ 7. **Use `scram-sha-256`** — md5 is deprecated (PG18 emits warnings on md5 password creation)