Raw SQL Grants
For advanced cases the presets don’t cover — specific tables, REVOKE, ALTER DEFAULT PRIVILEGES, materialized views, foreign servers — a database grant can include a sql field with Go templates that are run during role provisioning. ✓ TestIntegration_Proxy_RawSQLPermissions internal/proxy/proxy_integration_test.go:553
{ "databases": { "myapp": { "permissions": ["readonly"], "sql": [ "GRANT INSERT ON public.audit_log TO {{.Role}}", "GRANT USAGE ON SCHEMA analytics TO {{.Role}}", "GRANT SELECT ON ALL TABLES IN SCHEMA analytics TO {{.Role}}" ] } }}Template variables
Section titled “Template variables”| Variable | Value |
|---|---|
{{.Role}} | The dynamically created backend role name (e.g. wp_alice_laptop_myapp). Always quote-safe. |
{{.Database}} | The target database name. |
{{.User}} | The caller’s Tailscale login (loginName). |
Server-side gating
Section titled “Server-side gating”Raw SQL is disabled by default server-side via the [provisioning] section:
[provisioning]allow_raw_sql = false # rejects ACL grants that include `sql`When false, any grant carrying a sql field is treated as an authorization failure for that connection. Per-listener overrides let you enable raw SQL only on listeners that need it:
[listeners.postgres]allow_raw_sql = trueValidation
Section titled “Validation”Templates are parsed and validated before execution. Common attack shapes — injection attempts, multi-statement batches, structural malformations, disallowed statement types — are rejected at load time. ✓ TestValidateSQL_InjectionAttempts internal/provision/sqlvalidate_test.go:137 ✓ TestValidateSQL_RejectedStatementTypes internal/provision/sqlvalidate_test.go:98 ✓ TestValidateSQL_Malicious internal/provision/sqlvalidate_test.go:200 Only GRANT, REVOKE, and ALTER DEFAULT PRIVILEGES statements are accepted. ✓ TestValidateSQL_Grants internal/provision/sqlvalidate_test.go:8 ✓ TestValidateSQL_Revokes internal/provision/sqlvalidate_test.go:49 ✓ TestValidateSQL_AlterDefaultPrivileges internal/provision/sqlvalidate_test.go:71
Recommendations
Section titled “Recommendations”- Keep raw SQL grants short and idempotent — they run on every connect.
- Use them to add permissions on top of a preset, not to define the whole grant from scratch.
- Audit any grant containing
sqlcarefully — it has full backend-side capability subject only to theadmin_user’s privileges. - If you find yourself templating the same SQL in many grants, prefer a stored procedure on the backend.