Files
2026-02-13 09:12:11 +00:00

361 lines
9.0 KiB
Markdown

# Using Mock OAuth2 Server in CI/CD
This guide explains how to use the mock OAuth2 server infrastructure in continuous integration pipelines.
## GitHub Actions Configuration
### Running with Mock OAuth (Default)
The tests automatically use mock OAuth by default. No special configuration needed:
```yaml
name: Tests with Mock OAuth
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install -r requirements-dev.txt
- name: Run OAuth tests (mock)
run: |
pytest tests/test_oauth_integration_flows.py -v
```
### Running with Real OAuth (Using Secrets)
To test with real OAuth credentials (e.g., Authentik, Auth0):
```yaml
name: Tests with Real OAuth
on: [push, pull_request]
jobs:
test-real-oauth:
runs-on: ubuntu-latest
# Only run if secrets are available (not on external PRs)
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install -r requirements-dev.txt
- name: Run OAuth tests (real)
env:
AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }}
AUTHENTIK_CLIENT_SECRET: ${{ secrets.AUTHENTIK_CLIENT_SECRET }}
AUTHENTIK_CONFIG_URL: ${{ secrets.AUTHENTIK_CONFIG_URL }}
run: |
# Tests auto-detect real credentials and use them
pytest tests/test_oauth_integration_flows.py -v -m requires_external
```
### Hybrid Approach (Best Practice)
Run both mock and real tests in separate jobs:
```yaml
name: OAuth Tests
on: [push, pull_request]
jobs:
test-mock-oauth:
name: OAuth Tests (Mock)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install -r requirements-dev.txt
- name: Run mock OAuth tests
run: |
pytest tests/test_oauth_integration_flows.py \
-v \
-m "not requires_external"
test-real-oauth:
name: OAuth Tests (Real - Internal Only)
runs-on: ubuntu-latest
# Only run on internal commits where secrets are available
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install -r requirements-dev.txt
- name: Run real OAuth tests
env:
AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }}
AUTHENTIK_CLIENT_SECRET: ${{ secrets.AUTHENTIK_CLIENT_SECRET }}
AUTHENTIK_CONFIG_URL: ${{ secrets.AUTHENTIK_CONFIG_URL }}
run: |
pytest tests/test_oauth_integration_flows.py \
-v \
-m requires_external
```
## Required GitHub Secrets
To enable real OAuth testing, configure these secrets in your repository:
1. Go to **Settings → Secrets and variables → Actions**
2. Add the following secrets:
| Secret Name | Description | Example Value |
|-------------|-------------|---------------|
| `AUTHENTIK_CLIENT_ID` | OAuth client ID | `docuelevate-app` |
| `AUTHENTIK_CLIENT_SECRET` | OAuth client secret | `super-secret-value` |
| `AUTHENTIK_CONFIG_URL` | OIDC discovery URL | `https://auth.example.com/application/o/docuelevate/.well-known/openid-configuration` |
## Docker Service (Alternative to Testcontainers)
If you prefer not to use testcontainers in CI, you can run mock-oauth2-server as a service:
```yaml
name: Tests with OAuth Service
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
mock-oauth:
image: ghcr.io/navikt/mock-oauth2-server:2.1.1
ports:
- 8080:8080
options: >-
--health-cmd "wget -q -O /dev/null http://localhost:8080/default/.well-known/openid-configuration || exit 1"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install -r requirements-dev.txt
- name: Configure OAuth to use service
run: |
export OAUTH_MOCK_URL=http://localhost:8080
export USE_MOCK_OAUTH=true
- name: Run tests
run: |
pytest tests/test_oauth_integration_flows.py -v
```
## Forcing Mock or Real Mode
You can override the automatic detection with environment variables:
```bash
# Force mock mode (even if real credentials available)
export USE_MOCK_OAUTH=true
pytest tests/test_oauth_integration_flows.py -v
# Force real mode (will skip if credentials not available)
export USE_REAL_OAUTH=true
pytest tests/test_oauth_integration_flows.py -v
```
## Debugging OAuth Tests in CI
### View Container Logs
Add this step to debug mock OAuth server issues:
```yaml
- name: Show mock OAuth logs (on failure)
if: failure()
run: |
docker ps -a
docker logs $(docker ps -aq --filter ancestor=ghcr.io/navikt/mock-oauth2-server:2.1.1)
```
### Enable Verbose Logging
```yaml
- name: Run tests with verbose logging
run: |
pytest tests/test_oauth_integration_flows.py -vvs --log-cli-level=DEBUG
```
### Check Well-Known Endpoint
```yaml
- name: Verify mock OAuth server
run: |
curl -f http://localhost:8080/default/.well-known/openid-configuration || exit 1
```
## Performance Considerations
- **Mock OAuth**: ~1s startup time, tests run in <10s
- **Real OAuth**: Depends on network latency, typically <30s
- **Docker Service**: Fastest for CI (pre-started), ~0.5s overhead
## Security Best Practices
1.**Never commit real OAuth credentials** to the repository
2.**Use GitHub secrets** for real credentials
3.**Restrict real OAuth tests** to internal PRs only
4.**Use mock OAuth** for external/fork PRs
5.**Rotate secrets** regularly if compromised
## Troubleshooting
### Tests Skip with "OAuth credentials not available"
**Cause**: Real OAuth credentials not configured or not accessible.
**Solution**:
- For local dev: Use mock mode (default)
- For CI: Add secrets to GitHub repository settings
- Check secret availability: `if github.event_name == 'push'`
### Mock OAuth Server Won't Start
**Cause**: Docker not available or testcontainers can't start container.
**Solution**:
```yaml
- name: Start Docker
run: |
sudo systemctl start docker
docker ps
```
### Tests Timeout Waiting for Server
**Cause**: Server taking too long to start or health check failing.
**Solution**: Increase timeout in `conftest_oauth.py`:
```python
container.wait_for_ready(timeout=60) # Increase from 30
```
## Example: Complete GitHub Actions Workflow
```yaml
name: Full OAuth Testing Suite
on: [push, pull_request]
jobs:
# Fast mock OAuth tests (always run)
mock-oauth-tests:
name: OAuth Tests (Mock)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install -r requirements-dev.txt
- name: Run mock OAuth tests
run: |
pytest tests/test_oauth_integration_flows.py \
-v \
-m "not requires_external" \
--cov=app.auth \
--cov-report=term-missing
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage.xml
flags: oauth-mock
# Real OAuth tests (only for internal PRs/pushes)
real-oauth-tests:
name: OAuth Tests (Real - Internal)
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install -r requirements-dev.txt
- name: Run real OAuth tests
env:
AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }}
AUTHENTIK_CLIENT_SECRET: ${{ secrets.AUTHENTIK_CLIENT_SECRET }}
AUTHENTIK_CONFIG_URL: ${{ secrets.AUTHENTIK_CONFIG_URL }}
run: |
pytest tests/test_oauth_integration_flows.py \
-v \
-m requires_external
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage.xml
flags: oauth-real
```
This workflow:
- ✅ Runs mock tests on all PRs (fast, no secrets needed)
- ✅ Runs real tests only when secrets available
- ✅ Uploads separate coverage reports
- ✅ Provides detailed feedback