- Add Groups field to User struct with JSON storage - Include GetGroups() and SetGroups() helper methods - Extract groups from OIDC claims in FromClaim() - Add database migration 202509161200 for groups column - Update config-example.yaml with groups scope - Add comprehensive documentation and testing
318 lines
8.7 KiB
Markdown
318 lines
8.7 KiB
Markdown
# OIDC Groups Migration and Compatibility Plan
|
|
|
|
## Overview
|
|
|
|
This document outlines the migration strategy and backward compatibility considerations for the OIDC groups feature implementation.
|
|
|
|
## Database Migration Strategy
|
|
|
|
### Migration Details
|
|
- **Migration ID**: `202509161200`
|
|
- **Operation**: Add `groups` TEXT column to `users` table
|
|
- **Default Value**: Empty string (`""`)
|
|
- **Rollback Support**: Full rollback capability
|
|
|
|
### Safety Measures
|
|
|
|
#### Pre-Migration Validation
|
|
```sql
|
|
-- Check current user count and table structure
|
|
SELECT COUNT(*) FROM users;
|
|
DESCRIBE users;
|
|
```
|
|
|
|
#### Migration Steps
|
|
1. **Add Column**: `ALTER TABLE users ADD COLUMN groups TEXT DEFAULT '';`
|
|
2. **Verify Addition**: Check column exists and has correct type
|
|
3. **Index Creation**: No additional indexes needed initially
|
|
4. **Data Validation**: Verify all existing users have empty groups field
|
|
|
|
#### Rollback Procedure
|
|
```sql
|
|
-- Safe rollback - removes groups column
|
|
ALTER TABLE users DROP COLUMN groups;
|
|
```
|
|
|
|
### Migration Testing
|
|
|
|
#### Unit Tests
|
|
```go
|
|
func TestGroupsMigration(t *testing.T) {
|
|
// Test migration up
|
|
// Test rollback
|
|
// Test with existing data
|
|
// Test column constraints
|
|
}
|
|
```
|
|
|
|
#### Integration Tests
|
|
- Migration on database with existing users
|
|
- Rollback with populated groups data
|
|
- Performance impact measurement
|
|
- Concurrent operation safety
|
|
|
|
## Backward Compatibility Matrix
|
|
|
|
### API Compatibility
|
|
|
|
| Component | Before Groups | After Groups | Compatible |
|
|
|-----------|---------------|--------------|------------|
|
|
| User API Response | No groups field | Optional groups field | ✅ |
|
|
| OIDC Login Flow | Standard flow | Groups extraction added | ✅ |
|
|
| Database Schema | 10 columns | 11 columns | ✅ |
|
|
| Configuration | No groups config | Optional groups config | ✅ |
|
|
|
|
### Client Compatibility
|
|
|
|
#### Existing Headscale Clients
|
|
- ✅ **REST API Clients**: Groups field ignored if not expected
|
|
- ✅ **gRPC Clients**: Protobuf backward compatibility maintained
|
|
- ✅ **CLI Tools**: No impact on existing commands
|
|
- ✅ **Terraform Provider**: Groups field optional in responses
|
|
|
|
#### Management Interfaces
|
|
- ✅ **Headplane**: Ready for groups integration
|
|
- ✅ **Other UIs**: Groups field can be ignored safely
|
|
- ✅ **Custom Dashboards**: No breaking changes to existing queries
|
|
|
|
### Configuration Compatibility
|
|
|
|
#### Existing Configurations
|
|
```yaml
|
|
# This continues to work unchanged
|
|
oidc:
|
|
issuer: "https://your-provider.com"
|
|
client_id: "your-client-id"
|
|
client_secret: "your-secret"
|
|
```
|
|
|
|
#### Enhanced Configuration (Optional)
|
|
```yaml
|
|
# Groups extraction is entirely optional
|
|
oidc:
|
|
issuer: "https://your-provider.com"
|
|
client_id: "your-client-id"
|
|
client_secret: "your-secret"
|
|
extra_params:
|
|
groups_claim: "groups" # Optional groups extraction
|
|
```
|
|
|
|
## Deployment Strategy
|
|
|
|
### Phase 1: Infrastructure Preparation
|
|
1. **Database Backup**: Full backup before migration
|
|
2. **Monitoring Setup**: Enhanced logging for migration tracking
|
|
3. **Rollback Plan**: Tested rollback procedures
|
|
4. **Staging Validation**: Full testing in staging environment
|
|
|
|
### Phase 2: Migration Execution
|
|
1. **Maintenance Window**: Schedule appropriate downtime
|
|
2. **Migration Execution**: Run database migration
|
|
3. **Verification**: Confirm migration success
|
|
4. **Service Restart**: Restart Headscale with new code
|
|
|
|
### Phase 3: Feature Activation
|
|
1. **Configuration Update**: Add groups configuration if desired
|
|
2. **OIDC Provider**: Configure groups claims
|
|
3. **Testing**: Verify groups extraction working
|
|
4. **Monitoring**: Watch for any issues
|
|
|
|
### Phase 4: Validation
|
|
1. **User Login Tests**: Verify existing users can still login
|
|
2. **Groups Extraction**: Verify new logins extract groups
|
|
3. **API Responses**: Verify API clients handle groups field
|
|
4. **Performance**: Monitor for any performance impact
|
|
|
|
## Rollback Procedures
|
|
|
|
### Immediate Rollback (Same Session)
|
|
If issues detected during migration:
|
|
```bash
|
|
# Rollback database migration
|
|
headscale migration rollback 202509161200
|
|
|
|
# Restart with previous code
|
|
systemctl restart headscale
|
|
```
|
|
|
|
### Delayed Rollback (After Deployment)
|
|
If issues detected after feature deployment:
|
|
```bash
|
|
# 1. Disable groups extraction in config
|
|
# Remove or comment out groups_claim configuration
|
|
|
|
# 2. Restart service
|
|
systemctl restart headscale
|
|
|
|
# 3. (Optional) Rollback database if needed
|
|
headscale migration rollback 202509161200
|
|
```
|
|
|
|
### Emergency Rollback
|
|
Critical issues requiring immediate fix:
|
|
```bash
|
|
# Emergency config to disable groups
|
|
echo "HEADSCALE_DISABLE_GROUPS=true" >> /etc/headscale/env
|
|
systemctl restart headscale
|
|
|
|
# Full rollback when ready
|
|
git checkout previous-version
|
|
headscale migration rollback 202509161200
|
|
```
|
|
|
|
## Risk Mitigation
|
|
|
|
### Low-Risk Design Decisions
|
|
|
|
#### Optional Feature
|
|
- Groups extraction only happens if configured
|
|
- Existing OIDC flows continue unchanged
|
|
- No impact on non-OIDC authentication
|
|
|
|
#### Graceful Degradation
|
|
```go
|
|
// Groups parsing with error handling
|
|
func (u *User) GetGroups() []string {
|
|
if u.Groups == "" {
|
|
return []string{} // Safe empty default
|
|
}
|
|
|
|
var groups []string
|
|
if err := json.Unmarshal([]byte(u.Groups), &groups); err != nil {
|
|
log.Error().Err(err).Msg("Failed to unmarshal user groups")
|
|
return []string{} // Graceful failure
|
|
}
|
|
|
|
return groups
|
|
}
|
|
```
|
|
|
|
#### Database Safety
|
|
- Column addition is non-destructive
|
|
- Default values ensure consistency
|
|
- No foreign key constraints
|
|
- No unique constraints that could conflict
|
|
|
|
### Medium-Risk Considerations
|
|
|
|
#### Performance Impact
|
|
- **Risk**: Additional JSON parsing on user operations
|
|
- **Mitigation**: Lazy loading, caching, minimal parsing overhead
|
|
- **Monitoring**: Response time metrics for user operations
|
|
|
|
#### Storage Growth
|
|
- **Risk**: Groups data increases user table size
|
|
- **Mitigation**: JSON is compact, groups typically small
|
|
- **Monitoring**: Database size growth tracking
|
|
|
|
#### OIDC Provider Compatibility
|
|
- **Risk**: Different providers return groups differently
|
|
- **Mitigation**: Flexible claims configuration, error handling
|
|
- **Testing**: Multi-provider integration tests
|
|
|
|
### Risk Monitoring
|
|
|
|
#### Key Metrics
|
|
- Migration success/failure rates
|
|
- User login success rates before/after
|
|
- API response times
|
|
- Groups extraction success rates
|
|
- Database query performance
|
|
|
|
#### Alert Conditions
|
|
- Migration failures
|
|
- Increased login failures
|
|
- API response time degradation
|
|
- Groups parsing errors above threshold
|
|
|
|
## Testing Strategy
|
|
|
|
### Pre-Migration Testing
|
|
|
|
#### Unit Tests
|
|
- Database migration up/down
|
|
- Groups parsing/serialization
|
|
- OIDC claims extraction
|
|
- Error handling scenarios
|
|
|
|
#### Integration Tests
|
|
- Full OIDC flow with groups
|
|
- Multiple provider compatibility
|
|
- Migration with existing data
|
|
- API responses with/without groups
|
|
|
|
#### Performance Tests
|
|
- User login latency impact
|
|
- Database query performance
|
|
- Memory usage with groups data
|
|
- Concurrent operations
|
|
|
|
### Post-Migration Testing
|
|
|
|
#### Smoke Tests
|
|
- Existing users can login
|
|
- New users get groups extracted
|
|
- API endpoints respond correctly
|
|
- Admin operations work normally
|
|
|
|
#### Regression Tests
|
|
- All existing integration tests pass
|
|
- No functional regressions
|
|
- Configuration compatibility
|
|
- CLI tool compatibility
|
|
|
|
## Documentation Updates
|
|
|
|
### Admin Documentation
|
|
- Migration procedures
|
|
- Rollback instructions
|
|
- Troubleshooting guide
|
|
- Configuration examples
|
|
|
|
### API Documentation
|
|
- Groups field in user responses
|
|
- OIDC configuration options
|
|
- Error conditions and handling
|
|
- Migration impact notes
|
|
|
|
### Deployment Documentation
|
|
- Version compatibility matrix
|
|
- Upgrade procedures
|
|
- Monitoring recommendations
|
|
- Security considerations
|
|
|
|
## Success Criteria
|
|
|
|
### Migration Success
|
|
- ✅ Database migration completes without errors
|
|
- ✅ All existing functionality preserved
|
|
- ✅ No performance degradation > 5%
|
|
- ✅ Groups extraction works when configured
|
|
|
|
### Backward Compatibility Success
|
|
- ✅ Existing OIDC configurations continue working
|
|
- ✅ API clients handle responses correctly
|
|
- ✅ No breaking changes to public interfaces
|
|
- ✅ Rollback procedures tested and verified
|
|
|
|
### Feature Success
|
|
- ✅ Groups extracted from configured OIDC providers
|
|
- ✅ Groups data stored and retrieved correctly
|
|
- ✅ Integration with Headplane works as designed
|
|
- ✅ Documentation complete and accurate
|
|
|
|
## Long-term Maintenance
|
|
|
|
### Ongoing Responsibilities
|
|
- Monitor groups extraction accuracy
|
|
- Update provider-specific documentation
|
|
- Maintain test coverage for new providers
|
|
- Address compatibility issues as they arise
|
|
|
|
### Future Enhancements
|
|
- Group hierarchy support
|
|
- Custom claims mapping
|
|
- Groups-based ACL rules
|
|
- Performance optimizations
|
|
|
|
This plan ensures the OIDC groups feature can be safely deployed with minimal risk to existing Headscale installations while providing a clear path forward for enhanced functionality. |