aios-core 2.2.1 → 2.3.1
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.
- package/.aios-core/.session/current-session.json +14 -14
- package/.aios-core/cli/commands/migrate/validate.js +1 -1
- package/.aios-core/core/docs/session-update-pattern.md +17 -10
- package/.aios-core/core/elicitation/elicitation-engine.js +11 -6
- package/.aios-core/core/elicitation/session-manager.js +2 -1
- package/.aios-core/core/registry/registry-schema.json +166 -166
- package/.aios-core/core/registry/service-registry.json +6585 -6585
- package/.aios-core/core-config.yaml +12 -1
- package/.aios-core/data/agent-config-requirements.yaml +5 -5
- package/.aios-core/development/agents/devops.md +12 -0
- package/.aios-core/development/scripts/squad/README.md +112 -0
- package/.aios-core/development/scripts/squad/index.js +41 -0
- package/.aios-core/development/scripts/squad/squad-loader.js +359 -0
- package/.aios-core/development/scripts/squad/squad-validator.js +685 -0
- package/.aios-core/development/tasks/add-mcp.md +11 -5
- package/.aios-core/development/tasks/search-mcp.md +309 -0
- package/.aios-core/development/tasks/setup-mcp-docker.md +11 -8
- package/.aios-core/development/tasks/squad-creator-validate.md +151 -0
- package/.aios-core/docs/standards/AGENT-PERSONALIZATION-STANDARD-V1.md +3 -3
- package/.aios-core/index.d.ts +7 -7
- package/.aios-core/index.js +1 -1
- package/.aios-core/infrastructure/scripts/batch-creator.js +1 -1
- package/.aios-core/infrastructure/scripts/component-generator.js +1 -1
- package/.aios-core/infrastructure/templates/coderabbit.yaml.template +279 -279
- package/.aios-core/infrastructure/templates/github-workflows/ci.yml.template +169 -169
- package/.aios-core/infrastructure/templates/github-workflows/pr-automation.yml.template +330 -330
- package/.aios-core/infrastructure/templates/github-workflows/release.yml.template +196 -196
- package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -63
- package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -18
- package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -85
- package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -145
- package/.aios-core/infrastructure/tests/utilities-audit-results.json +500 -500
- package/.aios-core/infrastructure/tools/README.md +1 -1
- package/.aios-core/install-manifest.yaml +4 -1
- package/.aios-core/manifests/schema/manifest-schema.json +190 -190
- package/.aios-core/manifests/workers.csv +203 -203
- package/.aios-core/package.json +102 -102
- package/.aios-core/product/templates/activation-instructions-template.md +7 -7
- package/.aios-core/product/templates/adr.hbs +125 -125
- package/.aios-core/product/templates/component-react-tmpl.tsx +98 -98
- package/.aios-core/product/templates/dbdr.hbs +241 -241
- package/.aios-core/product/templates/engine/schemas/adr.schema.json +102 -102
- package/.aios-core/product/templates/engine/schemas/dbdr.schema.json +205 -205
- package/.aios-core/product/templates/engine/schemas/epic.schema.json +175 -175
- package/.aios-core/product/templates/engine/schemas/pmdr.schema.json +175 -175
- package/.aios-core/product/templates/engine/schemas/prd-v2.schema.json +300 -300
- package/.aios-core/product/templates/engine/schemas/prd.schema.json +152 -152
- package/.aios-core/product/templates/engine/schemas/story.schema.json +222 -222
- package/.aios-core/product/templates/engine/schemas/task.schema.json +154 -154
- package/.aios-core/product/templates/epic.hbs +212 -212
- package/.aios-core/product/templates/eslintrc-security.json +32 -32
- package/.aios-core/product/templates/github-actions-cd.yml +212 -212
- package/.aios-core/product/templates/github-actions-ci.yml +172 -172
- package/.aios-core/product/templates/pmdr.hbs +186 -186
- package/.aios-core/product/templates/prd-v2.0.hbs +216 -216
- package/.aios-core/product/templates/prd.hbs +201 -201
- package/.aios-core/product/templates/shock-report-tmpl.html +502 -502
- package/.aios-core/product/templates/story.hbs +263 -263
- package/.aios-core/product/templates/task.hbs +170 -170
- package/.aios-core/product/templates/tmpl-comment-on-examples.sql +158 -158
- package/.aios-core/product/templates/tmpl-migration-script.sql +91 -91
- package/.aios-core/product/templates/tmpl-rls-granular-policies.sql +104 -104
- package/.aios-core/product/templates/tmpl-rls-kiss-policy.sql +10 -10
- package/.aios-core/product/templates/tmpl-rls-roles.sql +135 -135
- package/.aios-core/product/templates/tmpl-rls-simple.sql +77 -77
- package/.aios-core/product/templates/tmpl-rls-tenant.sql +152 -152
- package/.aios-core/product/templates/tmpl-rollback-script.sql +77 -77
- package/.aios-core/product/templates/tmpl-seed-data.sql +140 -140
- package/.aios-core/product/templates/tmpl-smoke-test.sql +16 -16
- package/.aios-core/product/templates/tmpl-staging-copy-merge.sql +139 -139
- package/.aios-core/product/templates/tmpl-stored-proc.sql +140 -140
- package/.aios-core/product/templates/tmpl-trigger.sql +152 -152
- package/.aios-core/product/templates/tmpl-view-materialized.sql +133 -133
- package/.aios-core/product/templates/tmpl-view.sql +177 -177
- package/.aios-core/product/templates/token-exports-css-tmpl.css +240 -240
- package/.aios-core/quality/schemas/quality-metrics.schema.json +233 -233
- package/.aios-core/schemas/squad-schema.json +185 -0
- package/.aios-core/scripts/README.md +90 -322
- package/.aios-core/scripts/migrate-framework-docs.sh +300 -300
- package/.claude/rules/mcp-usage.md +116 -100
- package/LICENSE +48 -48
- package/README.md +3 -4
- package/bin/aios-init.js +11 -6
- package/bin/aios.js +2 -1
- package/package.json +2 -3
- package/packages/installer/package.json +39 -39
- package/packages/installer/tests/integration/environment-configuration.test.js +2 -2
- package/packages/installer/tests/unit/env-template.test.js +4 -3
- package/templates/squad/LICENSE +21 -21
- package/templates/squad/README.md +37 -37
- package/templates/squad/agents/example-agent.yaml +36 -36
- package/templates/squad/package.json +19 -19
- package/templates/squad/squad.yaml +25 -25
- package/templates/squad/tasks/example-task.yaml +46 -46
- package/templates/squad/templates/example-template.md +24 -24
- package/templates/squad/tests/example-agent.test.js +53 -53
- package/templates/squad/workflows/example-workflow.yaml +54 -54
- package/tools/diagnose-npx-issue.ps1 +96 -96
- package/tools/quick-diagnose.cmd +85 -85
- package/tools/quick-diagnose.ps1 +117 -117
- package/.aios-core/core/data/agent-config-requirements.yaml +0 -368
- package/.aios-core/core/data/aios-kb.md +0 -924
- package/.aios-core/core/data/workflow-patterns.yaml +0 -267
- package/.aios-core/product/templates/1mcp-config.yaml +0 -225
- package/.aios-core/scripts/context-detector.js +0 -226
- package/.aios-core/scripts/elicitation-engine.js +0 -385
- package/.aios-core/scripts/elicitation-session-manager.js +0 -300
- package/.claude/CLAUDE.md +0 -221
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
-- RLS Roles Template
|
|
2
|
-
-- Role-Based Access Control (RBAC) foundation for RLS policies
|
|
3
|
-
-- Created: :created_date
|
|
4
|
-
--
|
|
5
|
-
-- This template sets up the foundation for role-based RLS policies
|
|
6
|
-
|
|
7
|
-
-- =============================================================================
|
|
8
|
-
-- ROLES TABLE
|
|
9
|
-
-- =============================================================================
|
|
10
|
-
CREATE TABLE IF NOT EXISTS roles (
|
|
11
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
12
|
-
name TEXT NOT NULL UNIQUE,
|
|
13
|
-
description TEXT,
|
|
14
|
-
permissions JSONB DEFAULT '[]'::JSONB,
|
|
15
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
16
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
-- Insert default roles
|
|
20
|
-
INSERT INTO roles (name, description, permissions) VALUES
|
|
21
|
-
('admin', 'Full system access', '["*"]'::JSONB),
|
|
22
|
-
('editor', 'Can read and modify content', '["read", "write", "update"]'::JSONB),
|
|
23
|
-
('viewer', 'Read-only access', '["read"]'::JSONB),
|
|
24
|
-
('creator', 'Can create new content', '["read", "write"]'::JSONB)
|
|
25
|
-
ON CONFLICT (name) DO NOTHING;
|
|
26
|
-
|
|
27
|
-
-- =============================================================================
|
|
28
|
-
-- USER ROLES TABLE (Many-to-Many)
|
|
29
|
-
-- =============================================================================
|
|
30
|
-
CREATE TABLE IF NOT EXISTS user_roles (
|
|
31
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
32
|
-
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
33
|
-
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
|
34
|
-
granted_by UUID REFERENCES auth.users(id),
|
|
35
|
-
granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
36
|
-
expires_at TIMESTAMPTZ, -- NULL means never expires
|
|
37
|
-
|
|
38
|
-
UNIQUE(user_id, role_id)
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
-- Index for fast role lookups
|
|
42
|
-
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
|
|
43
|
-
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
|
|
44
|
-
|
|
45
|
-
-- =============================================================================
|
|
46
|
-
-- HELPER FUNCTIONS FOR RLS
|
|
47
|
-
-- =============================================================================
|
|
48
|
-
|
|
49
|
-
-- Check if user has a specific role
|
|
50
|
-
CREATE OR REPLACE FUNCTION has_role(role_name TEXT)
|
|
51
|
-
RETURNS BOOLEAN AS $$
|
|
52
|
-
BEGIN
|
|
53
|
-
RETURN EXISTS (
|
|
54
|
-
SELECT 1
|
|
55
|
-
FROM user_roles ur
|
|
56
|
-
JOIN roles r ON ur.role_id = r.id
|
|
57
|
-
WHERE ur.user_id = auth.uid()
|
|
58
|
-
AND r.name = role_name
|
|
59
|
-
AND (ur.expires_at IS NULL OR ur.expires_at > NOW())
|
|
60
|
-
);
|
|
61
|
-
END;
|
|
62
|
-
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;
|
|
63
|
-
|
|
64
|
-
-- Check if user has any of the specified roles
|
|
65
|
-
CREATE OR REPLACE FUNCTION has_any_role(role_names TEXT[])
|
|
66
|
-
RETURNS BOOLEAN AS $$
|
|
67
|
-
BEGIN
|
|
68
|
-
RETURN EXISTS (
|
|
69
|
-
SELECT 1
|
|
70
|
-
FROM user_roles ur
|
|
71
|
-
JOIN roles r ON ur.role_id = r.id
|
|
72
|
-
WHERE ur.user_id = auth.uid()
|
|
73
|
-
AND r.name = ANY(role_names)
|
|
74
|
-
AND (ur.expires_at IS NULL OR ur.expires_at > NOW())
|
|
75
|
-
);
|
|
76
|
-
END;
|
|
77
|
-
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;
|
|
78
|
-
|
|
79
|
-
-- Check if user has a specific permission
|
|
80
|
-
CREATE OR REPLACE FUNCTION has_permission(permission TEXT)
|
|
81
|
-
RETURNS BOOLEAN AS $$
|
|
82
|
-
BEGIN
|
|
83
|
-
RETURN EXISTS (
|
|
84
|
-
SELECT 1
|
|
85
|
-
FROM user_roles ur
|
|
86
|
-
JOIN roles r ON ur.role_id = r.id
|
|
87
|
-
WHERE ur.user_id = auth.uid()
|
|
88
|
-
AND (
|
|
89
|
-
r.permissions @> '["*"]'::JSONB
|
|
90
|
-
OR r.permissions @> to_jsonb(permission)
|
|
91
|
-
)
|
|
92
|
-
AND (ur.expires_at IS NULL OR ur.expires_at > NOW())
|
|
93
|
-
);
|
|
94
|
-
END;
|
|
95
|
-
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;
|
|
96
|
-
|
|
97
|
-
-- =============================================================================
|
|
98
|
-
-- RLS ON ROLES TABLES
|
|
99
|
-
-- =============================================================================
|
|
100
|
-
|
|
101
|
-
-- Roles table: Admins can manage, everyone can read
|
|
102
|
-
ALTER TABLE roles ENABLE ROW LEVEL SECURITY;
|
|
103
|
-
|
|
104
|
-
CREATE POLICY "roles_select" ON roles
|
|
105
|
-
FOR SELECT TO authenticated
|
|
106
|
-
USING (true);
|
|
107
|
-
|
|
108
|
-
CREATE POLICY "roles_admin" ON roles
|
|
109
|
-
FOR ALL TO authenticated
|
|
110
|
-
USING (has_role('admin'))
|
|
111
|
-
WITH CHECK (has_role('admin'));
|
|
112
|
-
|
|
113
|
-
-- User roles: Users see their own, admins see all
|
|
114
|
-
ALTER TABLE user_roles ENABLE ROW LEVEL SECURITY;
|
|
115
|
-
|
|
116
|
-
CREATE POLICY "user_roles_select" ON user_roles
|
|
117
|
-
FOR SELECT TO authenticated
|
|
118
|
-
USING (user_id = auth.uid() OR has_role('admin'));
|
|
119
|
-
|
|
120
|
-
CREATE POLICY "user_roles_admin" ON user_roles
|
|
121
|
-
FOR ALL TO authenticated
|
|
122
|
-
USING (has_role('admin'))
|
|
123
|
-
WITH CHECK (has_role('admin'));
|
|
124
|
-
|
|
125
|
-
-- =============================================================================
|
|
126
|
-
-- USAGE EXAMPLE IN OTHER POLICIES
|
|
127
|
-
-- =============================================================================
|
|
128
|
-
--
|
|
129
|
-
-- CREATE POLICY "my_table_select" ON my_table
|
|
130
|
-
-- FOR SELECT TO authenticated
|
|
131
|
-
-- USING (
|
|
132
|
-
-- user_id = auth.uid()
|
|
133
|
-
-- OR has_any_role(ARRAY['admin', 'viewer'])
|
|
134
|
-
-- );
|
|
135
|
-
--
|
|
1
|
+
-- RLS Roles Template
|
|
2
|
+
-- Role-Based Access Control (RBAC) foundation for RLS policies
|
|
3
|
+
-- Created: :created_date
|
|
4
|
+
--
|
|
5
|
+
-- This template sets up the foundation for role-based RLS policies
|
|
6
|
+
|
|
7
|
+
-- =============================================================================
|
|
8
|
+
-- ROLES TABLE
|
|
9
|
+
-- =============================================================================
|
|
10
|
+
CREATE TABLE IF NOT EXISTS roles (
|
|
11
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
12
|
+
name TEXT NOT NULL UNIQUE,
|
|
13
|
+
description TEXT,
|
|
14
|
+
permissions JSONB DEFAULT '[]'::JSONB,
|
|
15
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
16
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
-- Insert default roles
|
|
20
|
+
INSERT INTO roles (name, description, permissions) VALUES
|
|
21
|
+
('admin', 'Full system access', '["*"]'::JSONB),
|
|
22
|
+
('editor', 'Can read and modify content', '["read", "write", "update"]'::JSONB),
|
|
23
|
+
('viewer', 'Read-only access', '["read"]'::JSONB),
|
|
24
|
+
('creator', 'Can create new content', '["read", "write"]'::JSONB)
|
|
25
|
+
ON CONFLICT (name) DO NOTHING;
|
|
26
|
+
|
|
27
|
+
-- =============================================================================
|
|
28
|
+
-- USER ROLES TABLE (Many-to-Many)
|
|
29
|
+
-- =============================================================================
|
|
30
|
+
CREATE TABLE IF NOT EXISTS user_roles (
|
|
31
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
32
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
33
|
+
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
|
34
|
+
granted_by UUID REFERENCES auth.users(id),
|
|
35
|
+
granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
36
|
+
expires_at TIMESTAMPTZ, -- NULL means never expires
|
|
37
|
+
|
|
38
|
+
UNIQUE(user_id, role_id)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
-- Index for fast role lookups
|
|
42
|
+
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
|
|
44
|
+
|
|
45
|
+
-- =============================================================================
|
|
46
|
+
-- HELPER FUNCTIONS FOR RLS
|
|
47
|
+
-- =============================================================================
|
|
48
|
+
|
|
49
|
+
-- Check if user has a specific role
|
|
50
|
+
CREATE OR REPLACE FUNCTION has_role(role_name TEXT)
|
|
51
|
+
RETURNS BOOLEAN AS $$
|
|
52
|
+
BEGIN
|
|
53
|
+
RETURN EXISTS (
|
|
54
|
+
SELECT 1
|
|
55
|
+
FROM user_roles ur
|
|
56
|
+
JOIN roles r ON ur.role_id = r.id
|
|
57
|
+
WHERE ur.user_id = auth.uid()
|
|
58
|
+
AND r.name = role_name
|
|
59
|
+
AND (ur.expires_at IS NULL OR ur.expires_at > NOW())
|
|
60
|
+
);
|
|
61
|
+
END;
|
|
62
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;
|
|
63
|
+
|
|
64
|
+
-- Check if user has any of the specified roles
|
|
65
|
+
CREATE OR REPLACE FUNCTION has_any_role(role_names TEXT[])
|
|
66
|
+
RETURNS BOOLEAN AS $$
|
|
67
|
+
BEGIN
|
|
68
|
+
RETURN EXISTS (
|
|
69
|
+
SELECT 1
|
|
70
|
+
FROM user_roles ur
|
|
71
|
+
JOIN roles r ON ur.role_id = r.id
|
|
72
|
+
WHERE ur.user_id = auth.uid()
|
|
73
|
+
AND r.name = ANY(role_names)
|
|
74
|
+
AND (ur.expires_at IS NULL OR ur.expires_at > NOW())
|
|
75
|
+
);
|
|
76
|
+
END;
|
|
77
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;
|
|
78
|
+
|
|
79
|
+
-- Check if user has a specific permission
|
|
80
|
+
CREATE OR REPLACE FUNCTION has_permission(permission TEXT)
|
|
81
|
+
RETURNS BOOLEAN AS $$
|
|
82
|
+
BEGIN
|
|
83
|
+
RETURN EXISTS (
|
|
84
|
+
SELECT 1
|
|
85
|
+
FROM user_roles ur
|
|
86
|
+
JOIN roles r ON ur.role_id = r.id
|
|
87
|
+
WHERE ur.user_id = auth.uid()
|
|
88
|
+
AND (
|
|
89
|
+
r.permissions @> '["*"]'::JSONB
|
|
90
|
+
OR r.permissions @> to_jsonb(permission)
|
|
91
|
+
)
|
|
92
|
+
AND (ur.expires_at IS NULL OR ur.expires_at > NOW())
|
|
93
|
+
);
|
|
94
|
+
END;
|
|
95
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;
|
|
96
|
+
|
|
97
|
+
-- =============================================================================
|
|
98
|
+
-- RLS ON ROLES TABLES
|
|
99
|
+
-- =============================================================================
|
|
100
|
+
|
|
101
|
+
-- Roles table: Admins can manage, everyone can read
|
|
102
|
+
ALTER TABLE roles ENABLE ROW LEVEL SECURITY;
|
|
103
|
+
|
|
104
|
+
CREATE POLICY "roles_select" ON roles
|
|
105
|
+
FOR SELECT TO authenticated
|
|
106
|
+
USING (true);
|
|
107
|
+
|
|
108
|
+
CREATE POLICY "roles_admin" ON roles
|
|
109
|
+
FOR ALL TO authenticated
|
|
110
|
+
USING (has_role('admin'))
|
|
111
|
+
WITH CHECK (has_role('admin'));
|
|
112
|
+
|
|
113
|
+
-- User roles: Users see their own, admins see all
|
|
114
|
+
ALTER TABLE user_roles ENABLE ROW LEVEL SECURITY;
|
|
115
|
+
|
|
116
|
+
CREATE POLICY "user_roles_select" ON user_roles
|
|
117
|
+
FOR SELECT TO authenticated
|
|
118
|
+
USING (user_id = auth.uid() OR has_role('admin'));
|
|
119
|
+
|
|
120
|
+
CREATE POLICY "user_roles_admin" ON user_roles
|
|
121
|
+
FOR ALL TO authenticated
|
|
122
|
+
USING (has_role('admin'))
|
|
123
|
+
WITH CHECK (has_role('admin'));
|
|
124
|
+
|
|
125
|
+
-- =============================================================================
|
|
126
|
+
-- USAGE EXAMPLE IN OTHER POLICIES
|
|
127
|
+
-- =============================================================================
|
|
128
|
+
--
|
|
129
|
+
-- CREATE POLICY "my_table_select" ON my_table
|
|
130
|
+
-- FOR SELECT TO authenticated
|
|
131
|
+
-- USING (
|
|
132
|
+
-- user_id = auth.uid()
|
|
133
|
+
-- OR has_any_role(ARRAY['admin', 'viewer'])
|
|
134
|
+
-- );
|
|
135
|
+
--
|
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
-- Simple RLS Policy Template
|
|
2
|
-
-- Table: :table_name
|
|
3
|
-
-- Security Model: Simple owner-based access
|
|
4
|
-
-- Created: :created_date
|
|
5
|
-
--
|
|
6
|
-
-- This template creates a simple RLS policy where users can only
|
|
7
|
-
-- access rows they own (based on user_id column)
|
|
8
|
-
|
|
9
|
-
-- Enable RLS on table
|
|
10
|
-
ALTER TABLE :table_name ENABLE ROW LEVEL SECURITY;
|
|
11
|
-
|
|
12
|
-
-- =============================================================================
|
|
13
|
-
-- SIMPLE OWNER-BASED POLICY
|
|
14
|
-
-- =============================================================================
|
|
15
|
-
|
|
16
|
-
-- Drop existing policies if re-running
|
|
17
|
-
DROP POLICY IF EXISTS ":table_name_owner_policy" ON :table_name;
|
|
18
|
-
|
|
19
|
-
-- Single policy for all operations (SELECT, INSERT, UPDATE, DELETE)
|
|
20
|
-
-- Users can only access rows where user_id matches their auth.uid()
|
|
21
|
-
CREATE POLICY ":table_name_owner_policy"
|
|
22
|
-
ON :table_name
|
|
23
|
-
FOR ALL
|
|
24
|
-
TO authenticated
|
|
25
|
-
USING (auth.uid() = user_id)
|
|
26
|
-
WITH CHECK (auth.uid() = user_id);
|
|
27
|
-
|
|
28
|
-
-- =============================================================================
|
|
29
|
-
-- OPTIONAL: Allow service role to bypass RLS
|
|
30
|
-
-- =============================================================================
|
|
31
|
-
-- Note: This is enabled by default in Supabase
|
|
32
|
-
-- The service_role can access all rows regardless of RLS policies
|
|
33
|
-
-- Be careful with service_role key exposure
|
|
34
|
-
|
|
35
|
-
-- =============================================================================
|
|
36
|
-
-- OPTIONAL: Public read access (if needed)
|
|
37
|
-
-- =============================================================================
|
|
38
|
-
-- Uncomment if you want anonymous users to read data
|
|
39
|
-
--
|
|
40
|
-
-- DROP POLICY IF EXISTS ":table_name_public_read" ON :table_name;
|
|
41
|
-
-- CREATE POLICY ":table_name_public_read"
|
|
42
|
-
-- ON :table_name
|
|
43
|
-
-- FOR SELECT
|
|
44
|
-
-- TO anon
|
|
45
|
-
-- USING (is_public = true);
|
|
46
|
-
|
|
47
|
-
-- =============================================================================
|
|
48
|
-
-- VERIFICATION
|
|
49
|
-
-- =============================================================================
|
|
50
|
-
-- Test the policy:
|
|
51
|
-
--
|
|
52
|
-
-- 1. As authenticated user (should see only their rows):
|
|
53
|
-
-- SET LOCAL ROLE authenticated;
|
|
54
|
-
-- SET LOCAL request.jwt.claims = '{"sub": "user-uuid-here"}';
|
|
55
|
-
-- SELECT * FROM :table_name;
|
|
56
|
-
--
|
|
57
|
-
-- 2. As service role (should see all rows):
|
|
58
|
-
-- SET LOCAL ROLE service_role;
|
|
59
|
-
-- SELECT * FROM :table_name;
|
|
60
|
-
--
|
|
61
|
-
-- 3. As anonymous (should see nothing unless public_read enabled):
|
|
62
|
-
-- SET LOCAL ROLE anon;
|
|
63
|
-
-- SELECT * FROM :table_name;
|
|
64
|
-
|
|
65
|
-
-- =============================================================================
|
|
66
|
-
-- TABLE REQUIREMENTS
|
|
67
|
-
-- =============================================================================
|
|
68
|
-
-- This template assumes :table_name has a user_id column:
|
|
69
|
-
--
|
|
70
|
-
-- CREATE TABLE :table_name (
|
|
71
|
-
-- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
72
|
-
-- user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
73
|
-
-- -- other columns...
|
|
74
|
-
-- created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
75
|
-
-- );
|
|
76
|
-
--
|
|
77
|
-
-- CREATE INDEX idx_:table_name_user_id ON :table_name(user_id);
|
|
1
|
+
-- Simple RLS Policy Template
|
|
2
|
+
-- Table: :table_name
|
|
3
|
+
-- Security Model: Simple owner-based access
|
|
4
|
+
-- Created: :created_date
|
|
5
|
+
--
|
|
6
|
+
-- This template creates a simple RLS policy where users can only
|
|
7
|
+
-- access rows they own (based on user_id column)
|
|
8
|
+
|
|
9
|
+
-- Enable RLS on table
|
|
10
|
+
ALTER TABLE :table_name ENABLE ROW LEVEL SECURITY;
|
|
11
|
+
|
|
12
|
+
-- =============================================================================
|
|
13
|
+
-- SIMPLE OWNER-BASED POLICY
|
|
14
|
+
-- =============================================================================
|
|
15
|
+
|
|
16
|
+
-- Drop existing policies if re-running
|
|
17
|
+
DROP POLICY IF EXISTS ":table_name_owner_policy" ON :table_name;
|
|
18
|
+
|
|
19
|
+
-- Single policy for all operations (SELECT, INSERT, UPDATE, DELETE)
|
|
20
|
+
-- Users can only access rows where user_id matches their auth.uid()
|
|
21
|
+
CREATE POLICY ":table_name_owner_policy"
|
|
22
|
+
ON :table_name
|
|
23
|
+
FOR ALL
|
|
24
|
+
TO authenticated
|
|
25
|
+
USING (auth.uid() = user_id)
|
|
26
|
+
WITH CHECK (auth.uid() = user_id);
|
|
27
|
+
|
|
28
|
+
-- =============================================================================
|
|
29
|
+
-- OPTIONAL: Allow service role to bypass RLS
|
|
30
|
+
-- =============================================================================
|
|
31
|
+
-- Note: This is enabled by default in Supabase
|
|
32
|
+
-- The service_role can access all rows regardless of RLS policies
|
|
33
|
+
-- Be careful with service_role key exposure
|
|
34
|
+
|
|
35
|
+
-- =============================================================================
|
|
36
|
+
-- OPTIONAL: Public read access (if needed)
|
|
37
|
+
-- =============================================================================
|
|
38
|
+
-- Uncomment if you want anonymous users to read data
|
|
39
|
+
--
|
|
40
|
+
-- DROP POLICY IF EXISTS ":table_name_public_read" ON :table_name;
|
|
41
|
+
-- CREATE POLICY ":table_name_public_read"
|
|
42
|
+
-- ON :table_name
|
|
43
|
+
-- FOR SELECT
|
|
44
|
+
-- TO anon
|
|
45
|
+
-- USING (is_public = true);
|
|
46
|
+
|
|
47
|
+
-- =============================================================================
|
|
48
|
+
-- VERIFICATION
|
|
49
|
+
-- =============================================================================
|
|
50
|
+
-- Test the policy:
|
|
51
|
+
--
|
|
52
|
+
-- 1. As authenticated user (should see only their rows):
|
|
53
|
+
-- SET LOCAL ROLE authenticated;
|
|
54
|
+
-- SET LOCAL request.jwt.claims = '{"sub": "user-uuid-here"}';
|
|
55
|
+
-- SELECT * FROM :table_name;
|
|
56
|
+
--
|
|
57
|
+
-- 2. As service role (should see all rows):
|
|
58
|
+
-- SET LOCAL ROLE service_role;
|
|
59
|
+
-- SELECT * FROM :table_name;
|
|
60
|
+
--
|
|
61
|
+
-- 3. As anonymous (should see nothing unless public_read enabled):
|
|
62
|
+
-- SET LOCAL ROLE anon;
|
|
63
|
+
-- SELECT * FROM :table_name;
|
|
64
|
+
|
|
65
|
+
-- =============================================================================
|
|
66
|
+
-- TABLE REQUIREMENTS
|
|
67
|
+
-- =============================================================================
|
|
68
|
+
-- This template assumes :table_name has a user_id column:
|
|
69
|
+
--
|
|
70
|
+
-- CREATE TABLE :table_name (
|
|
71
|
+
-- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
72
|
+
-- user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
73
|
+
-- -- other columns...
|
|
74
|
+
-- created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
75
|
+
-- );
|
|
76
|
+
--
|
|
77
|
+
-- CREATE INDEX idx_:table_name_user_id ON :table_name(user_id);
|