Skip to content

Commit 2a8861f

Browse files
committed
docs: add docs for cloudsync auth and rls
1 parent a0a8b46 commit 2a8861f

File tree

2 files changed

+495
-0
lines changed

2 files changed

+495
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# CloudSync Authentication for Developers
2+
3+
## Direct Database Connections from Mobile
4+
5+
**NEVER have mobile/web clients connect directly to PostgreSQL, even with pgjwt.**
6+
7+
```
8+
❌ DANGEROUS (Don't do this)
9+
Mobile App → PostgreSQL (direct connection)
10+
- Exposes database to internet
11+
- Database credentials in app (can be decompiled)
12+
- Any client can execute SQL
13+
- No way to audit/control access
14+
- Doesn't scale
15+
16+
✅ CORRECT (Do this)
17+
Mobile App → Auth Server → PostgreSQL
18+
- App only talks to lightweight auth service
19+
- Auth server controls database access
20+
- Database hidden behind application layer
21+
- Credentials secure
22+
- Scalable and auditable
23+
```
24+
25+
**Even for quick testing:** Provide a real-world example (auth server), not a shortcut that teaches bad practices. Quick start should resemble production architecture.
26+
27+
---
28+
29+
## Understanding JWT Authentication Patterns
30+
31+
PostgreSQL projects use these main patterns:
32+
33+
### Core Patterns
34+
35+
1. **Database-native** — Validate tokens inside PostgreSQL
36+
- Best for: PostgREST, API-first architectures
37+
- Limitation: Requires JWKS endpoint, less flexibility
38+
- Database handles auth logic
39+
40+
2. **Application-layer****What CloudSync implements**
41+
- Validate tokens in the microservice
42+
- Pass user context to PostgreSQL (as JSON claims)
43+
- Full control, scalable, industry standard
44+
- Separates auth from database
45+
46+
3. **Hybrid** — Both API and DB validate
47+
- Application validates JWT signature
48+
- Database enforces RLS policies using claims
49+
- Defense-in-depth approach
50+
- Recommended for sensitive data
51+
52+
### Common Variations
53+
54+
4. **API Gateway Pattern** — Validation at gateway layer
55+
- Gateway validates JWT, extracts claims
56+
- Passes claims to backend microservices as headers/context
57+
- Still application-layer, just centralized
58+
59+
5. **Token Introspection Pattern** — Dynamic validation
60+
- Instead of signature validation, call auth service: "is this token valid?"
61+
- Better for token revocation, shorter-lived tokens
62+
- Adds latency (requires extra call per request)
63+
64+
6. **Service-to-Service JWT** — Internal microservice authentication
65+
- Services authenticate to each other with JWTs
66+
- Different from client authentication
67+
- Uses same JWT mechanisms
68+
69+
**CloudSync uses pattern 2 (application-layer)** with pattern 3 (RLS).
70+
71+
---
72+
73+
## PostgreSQL JWT Extensions: Why We Don't Recommend Them
74+
75+
**pg_session_jwt** (Neon Extension)
76+
- ✅ Validates JWTs at database layer with RLS integration
77+
- ✅ Good for: PostgREST, Postgres-centric apps
78+
- ❌ For CloudSync: Redundant (microservice already validates)
79+
- ❌ Adds DB-layer complexity without benefit
80+
- ❌ Not portable (Neon-specific initially)
81+
82+
**pgjwt** (GitHub Extension)
83+
- ✅ Generates + verifies JWTs in SQL
84+
- ❌ HS256-only (no key rotation, no RS256)
85+
-**CRITICAL:** Clients cannot connect directly to PostgreSQL
86+
-**DEPRECATED:** Removed in PostgreSQL 17+ (not forward-compatible)
87+
- Only use for: Learning (local development only, PostgreSQL 15 or earlier)
88+
89+
**Custom extensions you might find:**
90+
- Various community JWT extensions exist but have limited adoption
91+
- Most have the same issues: HS256-only, adds DB load, not portable
92+
- Evaluate against: production-readiness, portability, flexibility, maintenance
93+
94+
**Verdict:** Extensions add complexity without benefits for CloudSync. Application-layer validation (auth server) is:
95+
- ✅ Simpler (use standard JWT libraries)
96+
- ✅ More flexible (HS256, RS256, ES256, etc.)
97+
- ✅ More secure (database stays hidden)
98+
- ✅ Better separation of concerns
99+
- ✅ Scales independently
100+
-**Industry standard** (PostgREST uses this pattern with Auth0, custom auth servers, etc.)
101+
102+
**PostgREST (industry benchmark):**
103+
PostgREST doesn't generate JWTs. Instead, it validates JWTs from **external auth services** (Auth0, custom servers) and uses the JWT's `role` claim to control database access.
104+
105+
---
106+
107+
## Recommended Authentication Methods for CloudSync
108+
109+
### 1. Auth Server + HS256 (Development)
110+
**Best for:** Development and testing
111+
112+
```javascript
113+
// auth-server/server.js
114+
app.post('/token', (req, res) => {
115+
const token = jwt.sign(
116+
{ sub: 'user-123', role: 'authenticated' },
117+
process.env.JWT_SECRET,
118+
{ expiresIn: '24h', algorithm: 'HS256' }
119+
);
120+
res.json({ token });
121+
});
122+
```
123+
124+
**Pros:** Simple, separate from database, real-world pattern
125+
126+
**Cons:** Can't rotate keys without redeployment, secret must sync across services
127+
128+
### 2. Auth Server + RS256 (Production)
129+
**Best for:** Production deployments
130+
131+
```bash
132+
# Generate RSA keys once, persist to volume
133+
openssl genrsa -out private.pem 2048
134+
openssl rsa -in private.pem -pubout -out public.pem
135+
136+
# Auth server signs with private.pem
137+
# CloudSync fetches public key via JWKS endpoint
138+
# Keys can be rotated without redeployment
139+
```
140+
141+
**Pros:** Industry standard, asymmetric, key rotation, production-ready
142+
143+
**Cons:** More setup complexity
144+
145+
---
146+
147+
## Learning: pgjwt (Backend Developers Only)
148+
149+
**Not recommended for CloudSync testing**, but useful for understanding token generation:
150+
151+
```sql
152+
CREATE EXTENSION IF NOT EXISTS pgjwt;
153+
154+
-- Backend developer tests token generation
155+
SELECT sign(
156+
json_build_object('sub', 'user-123', 'role', 'authenticated'),
157+
'secret-key',
158+
'HS256'
159+
) AS token;
160+
161+
-- Test RLS with generated token
162+
SET request.jwt.claims = '{"sub":"user-123"}';
163+
SELECT * FROM todos; -- Verify RLS filters correctly
164+
```
165+
166+
**When to use:** Backend developers learning RLS, testing SQL token logic
167+
168+
**When NOT to use:** Testing CloudSync (still requires auth server for clients)
169+
170+
**Why not for CloudSync:** Even though pgjwt generates tokens, you still need an auth server because clients can't connect to PostgreSQL. Use a simple auth server instead — it's simpler, real-world, and PostgreSQL 17+ compatible.
171+
172+
---
173+
174+
## Client Apps (Android/Web/SQLite)
175+
176+
### How to get a JWT token
177+
178+
**Flow for all client types:**
179+
```
180+
Client app
181+
↓ (HTTP POST /auth/login)
182+
Auth Server (generates JWT)
183+
↓ (returns JWT)
184+
Client app (stores & uses JWT)
185+
↓ (HTTP request with Authorization: Bearer <token> through cloudsync extension)
186+
CloudSync Microservice
187+
```

0 commit comments

Comments
 (0)