- Update LICENSE file to Apache License 2.0 - Update README.md license section - Add changelog entry for license change - Provides better patent protection and enterprise adoption - Aligns with Kubernetes ecosystem standards
12 KiB
🔐 Passkey Auth for Kubernetes Nginx Ingress
A WebAuthn-based passkey authentication provider that integrates seamlessly with Kubernetes nginx ingress controllers. This service provides secure, passwordless authentication using passkeys (FIDO2/WebAuthn) and acts as an auth backend for nginx ingress.
✨ Features
- **Pa2. "User not found" during login:
- Ensure user is registered and approved (if required)
- Check that email address matches exactly
- WebAuthn errors:dless Authentication**: Uses WebAuthn/FIDO2 passkeys for secure authentication
- Email-Based Access Control: Users are identified by email addresses with configurable allowlists
- Nginx Ingress Integration: Works as an auth backend using nginx
auth_requestdirective - User Management: Admin interface for managing users and their approval status
- Access Control: Configure allowed email addresses and approval requirements
- Kubernetes Native: Designed specifically for Kubernetes deployment
- Persistent Storage: Uses SQLite with persistent volumes for data storage
- Modern UI: Clean, responsive web interface for user registration and management
🏗️ Architecture
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ User Browser │ │ Nginx Ingress │ │ Your App │
│ │ │ │ │ │
│ 1. Request │───▶│ 2. Auth Check │───▶│ 4. Serve App │
│ 4. Redirect │◀───│ 3. 401/302 │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
│ auth_request
▼
┌──────────────────┐
│ Passkey Auth │
│ │
│ - WebAuthn │
│ - User Mgmt │
│ - Session Mgmt │
└──────────────────┘
🚀 Quick Start
Prerequisites
- Kubernetes cluster with nginx ingress controller
- Docker
- kubectl configured to access your cluster
1. Clone and Build
git clone <repository-url>
cd passkey-auth
# Build the Docker image
./scripts/build.sh
2. Configure
Edit k8s/deployment.yaml to update:
# Update these values in the ConfigMap
webauthn:
rp_id: "your-domain.com" # Your domain
rp_origins:
- "https://your-domain.com" # Your domain with protocol
cors:
allowed_origins:
- "https://your-domain.com" # Your domain with protocol
auth:
session_secret: "your-secure-secret-key" # Generate a secure random string
3. Deploy to Kubernetes
# Deploy the passkey auth service
./scripts/deploy.sh
# Verify deployment
kubectl get pods -n passkey-auth
kubectl logs -f deployment/passkey-auth -n passkey-auth
4. Configure Your App's Ingress
Update your application's ingress to use passkey auth:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: your-app-ingress
annotations:
# Auth backend - points to passkey auth service
nginx.ingress.kubernetes.io/auth-url: "http://passkey-auth-service.passkey-auth.svc.cluster.local/auth"
# Redirect unauthorized users to login page
nginx.ingress.kubernetes.io/auth-signin: "https://your-domain.com/auth"
# Pass user info to your app
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-User,X-Auth-User-ID"
spec:
rules:
- host: your-app.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: your-app-service
port:
number: 80
5. Create Ingress for Passkey Auth
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: passkey-auth-ingress
namespace: passkey-auth
spec:
rules:
- host: your-domain.com
http:
paths:
- path: /auth
pathType: Prefix
backend:
service:
name: passkey-auth-service
port:
number: 80
Apply the ingress:
kubectl apply -f k8s/ingress-example.yaml
👥 User Management
Access the Admin Interface
- Navigate to
https://your-domain.com/authin your browser - You'll see the admin dashboard with three tabs:
- Register User: Register new users with passkeys
- Test Login: Test authentication
- Manage Users: View and manage all users
User Registration Flow
- Register: Admin enters email address and display name
- Email Validation: System checks if email is in the allowlist (if configured)
- Passkey Creation: Browser prompts for passkey creation (TouchID, Windows Hello, etc.)
- Approval: If
require_approvalis enabled, admin must approve users manually - Authentication: Users can now authenticate with their passkeys
User Approval Process
When require_approval is enabled in the configuration:
- New users register but cannot authenticate until approved
- Admin reviews pending users in the "Manage Users" tab
- Admin clicks "Approve" next to pending users
- Users can now authenticate with their passkeys
To approve a user:
- Navigate to the admin interface at
https://your-domain.com/auth - Click the "Manage Users" tab
- Find users with "Pending" status
- Click the "Approve" button next to the user
- Confirm the approval in the dialog
User Status Indicators:
- 🟢 Approved: User can authenticate
- 🟡 Pending: User registered but needs approval
Configuration Options
In config.yaml or environment variables:
auth:
require_approval: true # Require admin approval for new users
session_secret: "secret" # Session encryption key
allowed_emails: # Email allowlist (empty = allow all)
- "admin@company.com"
- "user@company.com"
Environment variable overrides:
WEBAUTHN_RP_ID: WebAuthn Relying Party ID (your domain)SESSION_SECRET: Session encryption secretDATABASE_PATH: SQLite database file pathPORT: Server port (default: 8080)ALLOWED_EMAILS: Comma-separated list of allowed emails
🔧 Development
Local Development
- Install Go dependencies:
go mod download
- Run locally:
# Update config.yaml for local development
go run main.go
- Access the interface:
http://localhost:8080
Project Structure
passkey-auth/
├── main.go # Application entry point
├── internal/
│ ├── auth/ # WebAuthn implementation
│ ├── config/ # Configuration management
│ ├── database/ # SQLite database layer
│ └── handlers/ # HTTP handlers
├── web/ # Static web files
├── k8s/ # Kubernetes manifests
├── scripts/ # Deployment scripts
└── config.yaml # Configuration file
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/register/begin |
POST | Start passkey registration |
/api/register/finish |
POST | Complete passkey registration |
/api/login/begin |
POST | Start passkey authentication |
/api/login/finish |
POST | Complete passkey authentication |
/api/logout |
POST | Logout user |
/auth |
GET | Nginx auth check endpoint |
/api/users |
GET | List all users (admin) |
/api/users |
POST | Create new user (admin) |
/api/users/{id} |
PUT | Update user (approve/admin) |
/api/users/{id} |
DELETE | Delete user (admin) |
/health |
GET | Health check |
🔒 Security Considerations
Production Deployment
- HTTPS Only: Always use HTTPS in production
- Secure Session Secret: Use a strong, random session secret
- Domain Configuration: Ensure
rp_idmatches your domain exactly - Network Security: Use Kubernetes network policies to restrict access
- Regular Backups: Backup the SQLite database regularly
Session Configuration
# Secure session configuration for production
auth:
session_secret: "your-256-bit-random-key" # Use a proper secret manager
Database Security
The SQLite database contains:
- User information (email addresses, display names)
- WebAuthn credentials (public keys, metadata)
- No passwords or private keys are stored
🔐 Email Access Control
Allowlist Configuration
You can control who can register by configuring an email allowlist:
# config.yaml
auth:
allowed_emails:
- "admin@yourcompany.com"
- "engineering@yourcompany.com"
- "support@yourcompany.com"
Or via environment variable:
export ALLOWED_EMAILS="admin@company.com,user1@company.com,user2@company.com"
Access Control Options
-
Open Registration (allowed_emails is empty or not set):
- Any email address can register
- Suitable for internal/trusted environments
-
Allowlist Mode (allowed_emails configured):
- Only specified email addresses can register
- Recommended for production environments
-
Combined with Approval:
- Users must be in allowlist AND get admin approval
- Maximum security for sensitive applications
📊 Monitoring
Health Checks
The service exposes a health endpoint at /health:
curl http://passkey-auth-service.passkey-auth.svc.cluster.local/health
Logs
View application logs:
kubectl logs -f deployment/passkey-auth -n passkey-auth
Metrics
For production, consider adding metrics collection:
- Authentication success/failure rates
- User registration rates
- Session duration statistics
🐛 Troubleshooting
Common Issues
-
Docker build failures with SQLite CGO errors:
- The Dockerfile uses Debian-based images (golang:1.21-bullseye) instead of Alpine
- This resolves musl vs glibc compatibility issues with go-sqlite3
- If you encounter
pread64orpwrite64errors, ensure you're using a glibc-based image
-
WebAuthn encoding errors (challenge not ArrayBuffer):
- The web interface includes base64url conversion functions
- Ensure you're using the included HTML file, not a custom frontend
- Binary WebAuthn data must be converted between base64url and ArrayBuffer
-
"User not found" during login:
- Ensure user is registered and approved (if required)
- Check that username matches exactly
-
WebAuthn errors:
- Verify
rp_idmatches your domain - Ensure HTTPS is used (required for WebAuthn)
- Check browser support for WebAuthn
- Verify
-
Auth backend not working:
- Verify ingress annotations are correct
- Check that the auth service is accessible from nginx
- Review nginx ingress controller logs
-
Session issues:
- Ensure session secret is consistent
- Check cookie settings (secure flag for HTTPS)
- Verify session storage is persistent
Debug Commands
# Check pod status
kubectl get pods -n passkey-auth
# View logs
kubectl logs deployment/passkey-auth -n passkey-auth
# Check service
kubectl get svc -n passkey-auth
# Test auth endpoint
kubectl exec -it deployment/passkey-auth -n passkey-auth -- wget -O- http://localhost:8080/health
# Port forward for local testing
kubectl port-forward svc/passkey-auth-service 8080:80 -n passkey-auth
🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
📄 License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
🙏 Acknowledgments
- go-webauthn - WebAuthn library for Go
- Gorilla - HTTP utilities for Go
- WebAuthn/FIDO2 specifications
- Kubernetes and nginx ingress controller teams
For support or questions, please create an issue in the repository.