496 lines
15 KiB
Markdown
496 lines
15 KiB
Markdown
# Authentication Rules Implementation Plan
|
|
|
|
## Executive Summary
|
|
|
|
This document outlines the implementation plan for adding whitelist/blacklist functionality to the Ginxsom Blossom server. The authentication rules system is **already coded** in [`src/request_validator.c`](src/request_validator.c) but lacks the database schema to function. This plan focuses on completing the implementation by adding the missing database tables and Admin API endpoints.
|
|
|
|
## Current State Analysis
|
|
|
|
### ✅ Already Implemented
|
|
- **Nostr event validation** - Full cryptographic verification (NIP-42 and Blossom)
|
|
- **Rule evaluation engine** - Complete priority-based logic in [`check_database_auth_rules()`](src/request_validator.c:1309-1471)
|
|
- **Configuration system** - `auth_rules_enabled` flag in config table
|
|
- **Admin API framework** - Authentication and endpoint structure in place
|
|
- **Documentation** - Comprehensive flow diagrams in [`docs/AUTH_API.md`](docs/AUTH_API.md)
|
|
|
|
### ❌ Missing Components
|
|
- **Database schema** - `auth_rules` table doesn't exist
|
|
- **Cache table** - `auth_rules_cache` for performance optimization
|
|
- **Admin API endpoints** - CRUD operations for managing rules
|
|
- **Migration script** - Database schema updates
|
|
- **Test suite** - Validation of rule enforcement
|
|
|
|
## Database Schema Design
|
|
|
|
### 1. auth_rules Table
|
|
|
|
```sql
|
|
-- Authentication rules for whitelist/blacklist functionality
|
|
CREATE TABLE IF NOT EXISTS auth_rules (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
rule_type TEXT NOT NULL, -- 'pubkey_blacklist', 'pubkey_whitelist',
|
|
-- 'hash_blacklist', 'mime_blacklist', 'mime_whitelist'
|
|
rule_target TEXT NOT NULL, -- The pubkey, hash, or MIME type to match
|
|
operation TEXT NOT NULL DEFAULT '*', -- 'upload', 'delete', 'list', or '*' for all
|
|
enabled INTEGER NOT NULL DEFAULT 1, -- 1 = enabled, 0 = disabled
|
|
priority INTEGER NOT NULL DEFAULT 100,-- Lower number = higher priority
|
|
description TEXT, -- Human-readable description
|
|
created_by TEXT, -- Admin pubkey who created the rule
|
|
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
|
|
-- Constraints
|
|
CHECK (rule_type IN ('pubkey_blacklist', 'pubkey_whitelist',
|
|
'hash_blacklist', 'mime_blacklist', 'mime_whitelist')),
|
|
CHECK (operation IN ('upload', 'delete', 'list', '*')),
|
|
CHECK (enabled IN (0, 1)),
|
|
CHECK (priority >= 0),
|
|
|
|
-- Unique constraint: one rule per type/target/operation combination
|
|
UNIQUE(rule_type, rule_target, operation)
|
|
);
|
|
|
|
-- Indexes for performance
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_type_target ON auth_rules(rule_type, rule_target);
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_operation ON auth_rules(operation);
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_enabled ON auth_rules(enabled);
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_priority ON auth_rules(priority);
|
|
```
|
|
|
|
### 2. auth_rules_cache Table
|
|
|
|
```sql
|
|
-- Cache for authentication decisions (5-minute TTL)
|
|
CREATE TABLE IF NOT EXISTS auth_rules_cache (
|
|
cache_key TEXT PRIMARY KEY NOT NULL, -- SHA-256 hash of request parameters
|
|
decision INTEGER NOT NULL, -- 1 = allow, 0 = deny
|
|
reason TEXT, -- Reason for decision
|
|
pubkey TEXT, -- Public key from request
|
|
operation TEXT, -- Operation type
|
|
resource_hash TEXT, -- Resource hash (if applicable)
|
|
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
expires_at INTEGER NOT NULL, -- Expiration timestamp
|
|
|
|
CHECK (decision IN (0, 1))
|
|
);
|
|
|
|
-- Index for cache expiration cleanup
|
|
CREATE INDEX IF NOT EXISTS idx_auth_cache_expires ON auth_rules_cache(expires_at);
|
|
```
|
|
|
|
### 3. Rule Type Definitions
|
|
|
|
| Rule Type | Purpose | Target Format | Priority Range |
|
|
|-----------|---------|---------------|----------------|
|
|
| `pubkey_blacklist` | Block specific users | 64-char hex pubkey | 1-99 (highest) |
|
|
| `hash_blacklist` | Block specific files | 64-char hex SHA-256 | 100-199 |
|
|
| `mime_blacklist` | Block file types | MIME type string | 200-299 |
|
|
| `pubkey_whitelist` | Allow specific users | 64-char hex pubkey | 300-399 |
|
|
| `mime_whitelist` | Allow file types | MIME type string | 400-499 |
|
|
|
|
### 4. Operation Types
|
|
|
|
- `upload` - File upload operations
|
|
- `delete` - File deletion operations
|
|
- `list` - File listing operations
|
|
- `*` - All operations (wildcard)
|
|
|
|
## Admin API Endpoints
|
|
|
|
### GET /api/rules
|
|
**Purpose**: List all authentication rules with filtering
|
|
**Authentication**: Required (admin pubkey)
|
|
**Query Parameters**:
|
|
- `rule_type` (optional): Filter by rule type
|
|
- `operation` (optional): Filter by operation
|
|
- `enabled` (optional): Filter by enabled status (true/false)
|
|
- `limit` (default: 100): Number of rules to return
|
|
- `offset` (default: 0): Pagination offset
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"data": {
|
|
"rules": [
|
|
{
|
|
"id": 1,
|
|
"rule_type": "pubkey_blacklist",
|
|
"rule_target": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
|
"operation": "upload",
|
|
"enabled": true,
|
|
"priority": 10,
|
|
"description": "Blocked spammer account",
|
|
"created_by": "admin_pubkey_here",
|
|
"created_at": 1704067200,
|
|
"updated_at": 1704067200
|
|
}
|
|
],
|
|
"total": 1,
|
|
"limit": 100,
|
|
"offset": 0
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /api/rules
|
|
**Purpose**: Create a new authentication rule
|
|
**Authentication**: Required (admin pubkey)
|
|
**Request Body**:
|
|
```json
|
|
{
|
|
"rule_type": "pubkey_blacklist",
|
|
"rule_target": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
|
"operation": "upload",
|
|
"priority": 10,
|
|
"description": "Blocked spammer account"
|
|
}
|
|
```
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Rule created successfully",
|
|
"data": {
|
|
"id": 1,
|
|
"rule_type": "pubkey_blacklist",
|
|
"rule_target": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
|
"operation": "upload",
|
|
"enabled": true,
|
|
"priority": 10,
|
|
"description": "Blocked spammer account",
|
|
"created_at": 1704067200
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /api/rules/:id
|
|
**Purpose**: Update an existing rule
|
|
**Authentication**: Required (admin pubkey)
|
|
**Request Body**:
|
|
```json
|
|
{
|
|
"enabled": false,
|
|
"priority": 20,
|
|
"description": "Updated description"
|
|
}
|
|
```
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Rule updated successfully",
|
|
"data": {
|
|
"id": 1,
|
|
"updated_fields": ["enabled", "priority", "description"]
|
|
}
|
|
}
|
|
```
|
|
|
|
### DELETE /api/rules/:id
|
|
**Purpose**: Delete an authentication rule
|
|
**Authentication**: Required (admin pubkey)
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Rule deleted successfully",
|
|
"data": {
|
|
"id": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /api/rules/clear-cache
|
|
**Purpose**: Clear the authentication rules cache
|
|
**Authentication**: Required (admin pubkey)
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Authentication cache cleared",
|
|
"data": {
|
|
"entries_cleared": 42
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /api/rules/test
|
|
**Purpose**: Test if a specific request would be allowed
|
|
**Authentication**: Required (admin pubkey)
|
|
**Query Parameters**:
|
|
- `pubkey` (required): Public key to test
|
|
- `operation` (required): Operation type (upload/delete/list)
|
|
- `hash` (optional): Resource hash
|
|
- `mime` (optional): MIME type
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"data": {
|
|
"allowed": false,
|
|
"reason": "Public key blacklisted",
|
|
"matched_rule": {
|
|
"id": 1,
|
|
"rule_type": "pubkey_blacklist",
|
|
"description": "Blocked spammer account"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1: Database Schema (Priority: HIGH)
|
|
**Estimated Time**: 2-4 hours
|
|
|
|
**Tasks**:
|
|
1. Create migration script `db/migrations/001_add_auth_rules.sql`
|
|
2. Add `auth_rules` table with indexes
|
|
3. Add `auth_rules_cache` table with indexes
|
|
4. Create migration runner script
|
|
5. Test migration on clean database
|
|
6. Test migration on existing database
|
|
|
|
**Deliverables**:
|
|
- Migration SQL script
|
|
- Migration runner bash script
|
|
- Migration documentation
|
|
|
|
**Validation**:
|
|
- Verify tables created successfully
|
|
- Verify indexes exist
|
|
- Verify constraints work correctly
|
|
- Test with sample data
|
|
|
|
### Phase 2: Admin API Endpoints (Priority: HIGH)
|
|
**Estimated Time**: 6-8 hours
|
|
|
|
**Tasks**:
|
|
1. Implement `GET /api/rules` endpoint
|
|
2. Implement `POST /api/rules` endpoint
|
|
3. Implement `PUT /api/rules/:id` endpoint
|
|
4. Implement `DELETE /api/rules/:id` endpoint
|
|
5. Implement `POST /api/rules/clear-cache` endpoint
|
|
6. Implement `GET /api/rules/test` endpoint
|
|
7. Add input validation for all endpoints
|
|
8. Add error handling and logging
|
|
|
|
**Deliverables**:
|
|
- C implementation in `src/admin_api.c`
|
|
- Header declarations in `src/ginxsom.h`
|
|
- API documentation updates
|
|
|
|
**Validation**:
|
|
- Test each endpoint with valid data
|
|
- Test error cases (invalid input, missing auth, etc.)
|
|
- Verify database operations work correctly
|
|
- Check response formats match specification
|
|
|
|
### Phase 3: Integration & Testing (Priority: HIGH)
|
|
**Estimated Time**: 4-6 hours
|
|
|
|
**Tasks**:
|
|
1. Create comprehensive test suite
|
|
2. Test rule creation and enforcement
|
|
3. Test cache functionality
|
|
4. Test priority ordering
|
|
5. Test whitelist default-deny behavior
|
|
6. Test performance with many rules
|
|
7. Document test scenarios
|
|
|
|
**Deliverables**:
|
|
- Test script `tests/auth_rules_test.sh`
|
|
- Performance benchmarks
|
|
- Test documentation
|
|
|
|
**Validation**:
|
|
- All test cases pass
|
|
- Performance meets requirements (<3ms per request)
|
|
- Cache hit rate >80% under load
|
|
- No memory leaks detected
|
|
|
|
### Phase 4: Documentation & Examples (Priority: MEDIUM)
|
|
**Estimated Time**: 2-3 hours
|
|
|
|
**Tasks**:
|
|
1. Update [`docs/AUTH_API.md`](docs/AUTH_API.md) with rule management
|
|
2. Create usage examples
|
|
3. Document common patterns (blocking users, allowing file types)
|
|
4. Create migration guide for existing deployments
|
|
5. Add troubleshooting section
|
|
|
|
**Deliverables**:
|
|
- Updated documentation
|
|
- Example scripts
|
|
- Migration guide
|
|
- Troubleshooting guide
|
|
|
|
## Code Changes Required
|
|
|
|
### 1. src/request_validator.c
|
|
**Status**: ✅ Already implemented - NO CHANGES NEEDED
|
|
|
|
The rule evaluation logic is complete in [`check_database_auth_rules()`](src/request_validator.c:1309-1471). Once the database tables exist, this code will work immediately.
|
|
|
|
### 2. src/admin_api.c
|
|
**Status**: ❌ Needs new endpoints
|
|
|
|
Add new functions:
|
|
```c
|
|
// Rule management endpoints
|
|
int handle_get_rules(FCGX_Request *request);
|
|
int handle_create_rule(FCGX_Request *request);
|
|
int handle_update_rule(FCGX_Request *request);
|
|
int handle_delete_rule(FCGX_Request *request);
|
|
int handle_clear_cache(FCGX_Request *request);
|
|
int handle_test_rule(FCGX_Request *request);
|
|
```
|
|
|
|
### 3. src/ginxsom.h
|
|
**Status**: ❌ Needs new declarations
|
|
|
|
Add function prototypes for new admin endpoints.
|
|
|
|
### 4. db/schema.sql
|
|
**Status**: ❌ Needs new tables
|
|
|
|
Add `auth_rules` and `auth_rules_cache` table definitions.
|
|
|
|
## Migration Strategy
|
|
|
|
### For New Installations
|
|
1. Run updated `db/init.sh` which includes new tables
|
|
2. No additional steps needed
|
|
|
|
### For Existing Installations
|
|
1. Create backup: `cp db/ginxsom.db db/ginxsom.db.backup`
|
|
2. Run migration: `sqlite3 db/ginxsom.db < db/migrations/001_add_auth_rules.sql`
|
|
3. Verify migration: `sqlite3 db/ginxsom.db ".schema auth_rules"`
|
|
4. Restart server to load new schema
|
|
|
|
### Rollback Procedure
|
|
1. Stop server
|
|
2. Restore backup: `cp db/ginxsom.db.backup db/ginxsom.db`
|
|
3. Restart server
|
|
|
|
## Performance Considerations
|
|
|
|
### Cache Strategy
|
|
- **5-minute TTL** balances freshness with performance
|
|
- **SHA-256 cache keys** prevent collision attacks
|
|
- **Automatic cleanup** of expired entries every 5 minutes
|
|
- **Cache hit target**: >80% under normal load
|
|
|
|
### Database Optimization
|
|
- **Indexes on all query columns** for fast lookups
|
|
- **Prepared statements** prevent SQL injection
|
|
- **Single connection** with proper cleanup
|
|
- **Query optimization** for rule evaluation order
|
|
|
|
### Expected Performance
|
|
- **Cache hit**: ~100μs (SQLite SELECT)
|
|
- **Cache miss**: ~2.4ms (full validation + rule checks)
|
|
- **Rule creation**: ~50ms (INSERT + cache invalidation)
|
|
- **Rule update**: ~30ms (UPDATE + cache invalidation)
|
|
|
|
## Security Considerations
|
|
|
|
### Input Validation
|
|
- Validate all rule_type values against enum
|
|
- Validate pubkey format (64 hex chars)
|
|
- Validate hash format (64 hex chars)
|
|
- Validate MIME type format
|
|
- Sanitize description text
|
|
|
|
### Authorization
|
|
- All rule management requires admin pubkey
|
|
- Verify Nostr event signatures
|
|
- Check event expiration
|
|
- Log all rule changes with admin pubkey
|
|
|
|
### Attack Mitigation
|
|
- **Rule flooding**: Limit total rules per type
|
|
- **Cache poisoning**: Cryptographic cache keys
|
|
- **Priority manipulation**: Validate priority ranges
|
|
- **Whitelist bypass**: Default-deny when whitelist exists
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
- Rule creation with valid data
|
|
- Rule creation with invalid data
|
|
- Rule update operations
|
|
- Rule deletion
|
|
- Cache operations
|
|
- Priority ordering
|
|
|
|
### Integration Tests
|
|
- End-to-end request flow
|
|
- Multiple rules interaction
|
|
- Cache hit/miss scenarios
|
|
- Whitelist default-deny behavior
|
|
- Performance under load
|
|
|
|
### Security Tests
|
|
- Invalid admin pubkey rejection
|
|
- Expired event rejection
|
|
- SQL injection attempts
|
|
- Cache poisoning attempts
|
|
- Priority bypass attempts
|
|
|
|
## Success Criteria
|
|
|
|
### Functional Requirements
|
|
- ✅ Rules can be created via Admin API
|
|
- ✅ Rules can be updated via Admin API
|
|
- ✅ Rules can be deleted via Admin API
|
|
- ✅ Rules are enforced during request validation
|
|
- ✅ Cache improves performance significantly
|
|
- ✅ Priority ordering works correctly
|
|
- ✅ Whitelist default-deny works correctly
|
|
|
|
### Performance Requirements
|
|
- ✅ Cache hit latency <200μs
|
|
- ✅ Full validation latency <3ms
|
|
- ✅ Cache hit rate >80% under load
|
|
- ✅ No memory leaks
|
|
- ✅ Database queries optimized
|
|
|
|
### Security Requirements
|
|
- ✅ Admin authentication required
|
|
- ✅ Input validation prevents injection
|
|
- ✅ Audit logging of all changes
|
|
- ✅ Cache keys prevent poisoning
|
|
- ✅ Whitelist bypass prevented
|
|
|
|
## Timeline Estimate
|
|
|
|
| Phase | Duration | Dependencies |
|
|
|-------|----------|--------------|
|
|
| Phase 1: Database Schema | 2-4 hours | None |
|
|
| Phase 2: Admin API | 6-8 hours | Phase 1 |
|
|
| Phase 3: Testing | 4-6 hours | Phase 2 |
|
|
| Phase 4: Documentation | 2-3 hours | Phase 3 |
|
|
| **Total** | **14-21 hours** | Sequential |
|
|
|
|
## Next Steps
|
|
|
|
1. **Review this plan** with stakeholders
|
|
2. **Create Phase 1 migration script** in `db/migrations/`
|
|
3. **Test migration** on development database
|
|
4. **Implement Phase 2 endpoints** in `src/admin_api.c`
|
|
5. **Create test suite** in `tests/auth_rules_test.sh`
|
|
6. **Update documentation** in `docs/`
|
|
7. **Deploy to production** with migration guide
|
|
|
|
## Conclusion
|
|
|
|
The authentication rules system is **90% complete** - the core logic exists and is well-tested. This implementation plan focuses on the final 10%: adding database tables and Admin API endpoints. The work is straightforward, well-scoped, and can be completed in 2-3 days of focused development.
|
|
|
|
The system will provide powerful whitelist/blacklist functionality while maintaining the performance and security characteristics already present in the codebase. |