This directory contains a complete local development setup for testing MinIO with Keycloak OIDC authentication and opkssh SSH certificate-based authentication.
graph TD
subgraph "Client Access"
Browser[Web Browser]
SSH[SSH Client]
S3Client[S3 Client/CLI]
end
subgraph "WAF Layer"
WAF[Coraza WAF<br/>Caddy<br/>:8080, :8082, :8443]
end
subgraph "Authentication"
Keycloak[Keycloak<br/>OIDC Provider<br/>HTTP: :8082<br/>HTTPS: :8443]
DB[(MariaDB<br/>:3306)]
end
subgraph "Storage & Services"
MinIO[MinIO<br/>S3 API<br/>:9000]
SSHServer[SSH Server<br/>opkssh<br/>:2222]
end
Browser --> WAF
S3Client --> WAF
SSH --> SSHServer
WAF --> Keycloak
WAF --> MinIO
Keycloak --> DB
SSHServer -.->|HTTPS Proxy| WAF
style WAF fill:#ff9800
style Keycloak fill:#4caf50
style MinIO fill:#2196f3
style SSHServer fill:#9c27b0
style DB fill:#607d8b
- Docker and Docker Compose
- macOS, Linux, or Windows with WSL2
- opkssh CLI tool (installation instructions below)
./setup-local.shThis script will:
- Build the Caddy WAF image
- Start services and generate Caddy's self-signed CA certificate
- Extract and trust the CA certificate on your system
- Start all services (MariaDB, Keycloak, MinIO, WAF, SSH server)
Note: You'll be prompted for your sudo password to trust the certificate.
macOS:
brew tap openpubkey/opkssh
brew install opksshLinux:
curl -L https://github.com/openpubkey/opkssh/releases/latest/download/opkssh-linux-amd64 -o opkssh
chmod +x opkssh
sudo mv opkssh /usr/local/bin/Windows:
curl https://github.com/openpubkey/opkssh/releases/latest/download/opkssh-windows-amd64.exe -o opkssh.exeopkssh login --provider="https://localhost:8443/realms/minio_realm,opkssh-client"This will:
- Open your browser to Keycloak login
- Use credentials:
test@test.com/test - Generate an SSH certificate valid for 24 hours
ssh -p 2222 testuser@localhostYou should be logged in without a password using your OIDC identity!
| Service | URL | Credentials |
|---|---|---|
| MinIO Console | http://localhost:8080 | minioadmin / minioadmin |
| MinIO API | http://localhost:8081 | - |
| Keycloak (HTTP) | http://localhost:8082 | admin / admin |
| Keycloak (HTTPS) | https://localhost:8443 | admin / admin |
| SSH Server | ssh://localhost:2222 | opkssh certificate |
docker-compose/
├── setup-local.sh # Local setup script
├── setup-azure-config.sh # Azure configuration helper
├── docker-compose.yml # Main local services
├── docker-compose.external-test.yml # External Azure testing
├── Dockerfile.ssh-server # Local SSH server with opkssh
├── Dockerfile.ssh-external-test # External SSH server for Azure
├── docker-entrypoint.sh # SSH server startup script
├── Caddyfile.local # Caddy WAF configuration
├── minio-realm-config.json # Keycloak realm import
├── opk-providers-local/ # opkssh config for local dev
│ └── providers
├── opk-auth_id-local/ # opkssh auth mapping for local
│ └── auth_id
├── opk-providers-azure/ # opkssh config for Azure (gitignored content)
│ └── providers
├── opk-auth_id-azure/ # opkssh auth mapping for Azure (gitignored content)
│ └── auth_id
└── TESTING-OPKSSH.md # Detailed opkssh testing guide
Used by docker-compose.yml for local development:
- Issuer:
https://localhost:8443/realms/minio_realm - Test user:
test@test.com→ Linux usertestuser
These files are committed to the repository.
Used by docker-compose.external-test.yml for testing against Azure deployment:
- Issuer:
https://<YOUR-FQDN>:8444/realms/minio_realm - Test user:
test@test.com→ Linux usertestuser
Important: These files contain your Azure FQDN and are gitignored. Use the helper script to configure them:
./setup-azure-config.sh testminio.germanywestcentral.cloudapp.azure.com./setup-azure-config.sh <YOUR-AZURE-FQDN> [PORT]
# Example:
./setup-azure-config.sh testminio.germanywestcentral.cloudapp.azure.com 8444# Copy the certificate from your Azure deployment
cp /path/to/azure-cert.pem ./minio-cert.pemdocker-compose -f docker-compose.external-test.yml up -dopkssh login --provider="https://<YOUR-FQDN>:8444/realms/minio_realm,opkssh-client"ssh -p 2223 testuser@localhostNote: The external test server runs on port 2223 (not 2222) to avoid conflicts with local testing.
- Local: Uses Caddy's auto-generated self-signed certificate
- Azure: Requires your Azure deployment's certificate as
minio-cert.pem - Certificates (
*.crt,*.pem,*.key) are gitignored for security
- SSH certificates expire after 24 hours
- Re-run
opkssh logindaily to refresh - No long-lived SSH keys needed - better security!
Change these in production:
- Admin:
admin/admin - Test user:
test@test.com/test
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f ssh-server
docker-compose logs -f keycloak# All services
docker-compose restart
# Specific service
docker-compose restart ssh-serverdocker-compose downdocker-compose build ssh-server
docker-compose up -d ssh-server# Stop and remove all containers, volumes
docker-compose down -v
# Remove generated certificate
rm -f caddy-root-ca.crt
# Run setup again
./setup-local.shCheck your certificate:
ssh-keygen -L -f ~/.ssh/id_ecdsa-cert.pubLook for:
- Valid: Should show current time to expiration
- Principals: Should be empty (opkssh handles this)
Re-login if expired:
opkssh login --provider="https://localhost:8443/realms/minio_realm,opkssh-client"macOS:
# Re-run certificate installation
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ./caddy-root-ca.crtLinux:
sudo cp ./caddy-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificatesCheck service status:
docker-compose psView error logs:
docker-compose logsCheck opk config file permissions:
docker exec ssh-test-server ls -la /etc/opk/Both files should be 640 (rw-r-----) owned by opksshuser.
The entrypoint script fixes this automatically, but if issues persist:
docker-compose restart ssh-serverVerify Keycloak is running:
curl http://localhost:8082/realms/minio_realm/.well-known/openid-configurationVerify HTTPS works:
curl https://localhost:8443/realms/minio_realm/.well-known/openid-configurationTest manually:
docker exec ssh-test-server /usr/local/bin/opkssh verify testuser "$(cat ~/.ssh/id_ecdsa-cert.pub)" ecdsa-sha2-nistp256Common errors:
- Policy file permissions: Fixed by entrypoint script
- Certificate not trusted: Certificate should be auto-installed on startup
- Cannot reach Keycloak: Check socat proxy is running
- TESTING-OPKSSH.md - Detailed opkssh setup and testing guide
- opkssh GitHub - Official opkssh documentation
- Keycloak Docs - Keycloak configuration
When modifying the setup:
-
Never commit certificates:
*.crt,*.pem,*.keyare gitignoredcaddy-root-ca.crtis generated locally
-
Keep Azure configs separate:
opk-*-azure/folder structure is committed- File contents with Azure FQDNs are gitignored
- Use
setup-azure-config.shto generate them
-
Test both environments:
- Local:
docker-compose up - External:
docker-compose -f docker-compose.external-test.yml up
- Local:
- ✅ Test MinIO OIDC login via web console
- ✅ Test opkssh SSH certificate authentication
- ✅ Add additional Keycloak users
- ✅ Configure group-based access control
- 🚀 Deploy to Azure using Terraform in parent directory