rls-patterns
>
pinned to #a10f722updated 2 weeks ago
Ask your AI client: “install skills/rls-patterns”.
Requires the metahub MCP server installed in your client. Set up MCP.
mh install skills/rls-patternsmetahub onboarded this repo on the author's behalf.
If you own github.com/bybren-llc/safe-agentic-workflow on GitHub, claim the listing to take over publishing. Your claim preserves the existing eval history and badges; only the curator label is replaced with verified-publisher on your next publish.
Stars
363
Last commit
2 weeks ago
Latest release
published
- #agile-methodology
- #ai-agents
- #ai-assisted-development
- #claude-code
- #commands
- #dark-factory
- #developer-tools
- #evidence-based-development
- #harness
- #hooks
- #methodology
- #multi-agent
- #safe-framework
- #scaled-agile-framework
- #skills
- #software-development
- #software-engineering
- #task-orchestration
- #whitepaper
About this skill
Pulled from SKILL.md at publish time.
> **TEMPLATE**: This skill uses `{{PLACEHOLDER}}` tokens. Replace with your project values before use.
Evaluation report
WarningsAutomated checks the publisher passed at publish time — structure, docs, safety, and whether the artifact behaves as claimed.a10f722· 2 weeks ago
Documentation
41Description qualitywarn
36 words · 251 chars — manifest description is empty; graded the GitHub repo description instead
A skill's manifest description doubles as its trigger — add one to SKILL.md (15+ words, e.g. “use this skill when …”).
README is present and substantial
69,138 chars · 18 sections · 28 code blocks
Tags / topics declared
19 total — agile-methodology, ai-agents, ai-assisted-development, claude-code, commands, dark-factory (+13)
README has usage / example sections
found: Quick Start · Getting Started · Installation
Homepage / docs URL declared
https://jscottgraham.us
Release history
1- releasecurrenta10f722warn2 weeks ago
Contents
TEMPLATE: This skill uses
{{PLACEHOLDER}}tokens. Replace with your project values before use.
Purpose
Enforce Row Level Security (RLS) patterns for all database operations. This skill ensures data isolation and prevents cross-user data access at the database level.
When This Skill Applies
- Writing any database query (ORM or raw SQL)
- Creating or modifying API routes that access the database
- Implementing webhook handlers that write to the database
- Working with user data, payments, subscriptions, or enrollments
- Accessing admin-only tables
Critical Rules
NEVER Do This
// FORBIDDEN - Direct DB calls bypass RLS
const user = await db.user.findUnique({ where: { user_id } });
// FORBIDDEN - No context set
const payments = await db.payments.findMany();
Linting will block direct DB calls. See linting configuration for enforcement rules.
ALWAYS Do This
import {
withUserContext,
withAdminContext,
withSystemContext,
} from "{{RLS_IMPORT}}";
// CORRECT - User context for user operations
const user = await withUserContext(db, userId, async (client) => {
return client.user.findUnique({ where: { user_id: userId } });
});
// CORRECT - Admin context for admin operations
const webhooks = await withAdminContext(db, userId, async (client) => {
return client.webhook_events.findMany();
});
// CORRECT - System context for webhooks/background tasks
const event = await withSystemContext(db, "webhook", async (client) => {
return client.webhook_events.create({ data: eventData });
});
Context Helper Reference
withUserContext(db, userId, callback)
Use for: All user-facing operations
- User profile access
- Payment history
- Subscription management
- Enrollments and personal data
const payments = await withUserContext(db, userId, async (client) => {
return client.payments.findMany({ where: { user_id: userId } });
});
withAdminContext(db, userId, callback)
Use for: Admin-only operations (requires admin role)
- Viewing all webhook events
- Managing disputes
- Accessing payment failures
const disputes = await withAdminContext(db, adminUserId, async (client) => {
return client.disputes.findMany();
});
withSystemContext(db, contextType, callback)
Use for: Webhooks and background jobs
- Webhook handlers (Stripe, auth provider, etc.)
- Background job processing
- System-initiated operations
await withSystemContext(db, "webhook", async (client) => {
await client.payments.create({ data: paymentData });
});
Admin Pages: Force Dynamic Rendering
CRITICAL: Admin pages using RLS queries MUST force runtime rendering (in Next.js):
// REQUIRED - RLS context unavailable at build time
export const dynamic = "force-dynamic";
async function getAdminData() {
return await withAdminContext(db, userId, async (client) => {
return client.someTable.findMany();
});
}
Without forced dynamic rendering, frameworks may try to pre-render at build time, causing "permission denied" errors.
Protected Tables
User Data Tables (User Isolation)
| Table | Policy Type | Access |
|---|---|---|
user | User isolation | Own data only |
payments | User isolation | Own payments only |
subscriptions | User isolation | Own subscriptions only |
invoices | User isolation | Own invoices only |
Admin/System Tables (Role-Based)
| Table | Policy Type | Access |
|---|---|---|
webhook_events | Admin+System | Admins and webhooks only |
disputes | Admin only | Admins only |
payment_failures | Admin only | Admins only |
Testing Requirements
Always test with the application-level DB user role (not a superuser):
# Basic RLS functionality test
{{RLS_TEST_COMMAND}}
# Comprehensive security validation
{{RLS_VALIDATION_COMMAND}}
Common Patterns
API Route with User Context
import { NextResponse } from "next/server";
import { requireAuth } from "{{AUTH_IMPORT}}";
import { withUserContext } from "{{RLS_IMPORT}}";
import { db } from "{{DB_IMPORT}}";
export async function GET() {
const { userId } = await requireAuth();
const payments = await withUserContext(db, userId, async (client) => {
return client.payments.findMany({
where: { user_id: userId },
orderBy: { created_at: "desc" },
});
});
return NextResponse.json(payments);
}
Webhook Handler with System Context
import { withSystemContext } from "{{RLS_IMPORT}}";
import { db } from "{{DB_IMPORT}}";
export async function POST(req: Request) {
// Verify webhook signature first...
await withSystemContext(db, "webhook", async (client) => {
await client.webhook_events.create({
data: {
event_type: event.type,
payload: event.data,
processed_at: new Date(),
},
});
});
return new Response("OK", { status: 200 });
}
Authoritative References
- RLS Implementation Guide:
docs/database/RLS_IMPLEMENTATION_GUIDE.md - RLS Policy Catalog:
docs/database/RLS_POLICY_CATALOG.md - Migration SOP:
docs/database/RLS_DATABASE_MIGRATION_SOP.md - Linting Rules: Check linting config for direct DB call enforcement
- RLS Context Helpers:
{{RLS_CONTEXT_FILE}}
Reviews
No reviews yet. Be the first.
Related
orchestration-patterns
>
migration-patterns
>
deployment-sop
>
mh install skills/rls-patterns