Courier Examples and Tutorials¶
This page provides worked configuration examples for common Courier deployment scenarios. Each example includes a complete YAML configuration and notes on any environment-specific requirements.
For a full description of every configuration option, see the Courier Configuration Reference.
Example 1: Linux Server — Local Key Generation via Bridge¶
A Courier running on a Linux server with no direct internet access, routing through a Bridge, generating keys locally, and restarting Nginx on successful renewal.
api:
base_url: https://bridge-prod-01.internal.example.com
version: v1
timeout_seconds: 30
verify_tls: true
retries: 3
retry_backoff: 60
auth:
uuid: cour_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
method: client_secret
client_id: ${ZAITA_CLIENT_ID}
client_secret: ${ZAITA_CLIENT_SECRET}
certificate:
output_dir: /etc/ssl/zaita
cert_filename: nginx-cert
key_filename: nginx-key
generate_keys_locally: true
key_algorithm: ecdsa
key_size: 384
digest: sha-384
certificate_validity_period: 90
renewal_threshold_days: 30
common_name: "web.example.com"
subject_alternative_names: "www.web.example.com"
organization: "Example Org"
country: "AU"
on_success: "/bin/bash /opt/scripts/restart-nginx.sh"
on_failure: "/bin/bash /opt/scripts/alert.sh"
logging:
level: info
file: /var/log/zaita-courier.log
Cron schedule:
0 */12 * * * /usr/bin/zaita-courier generate -c /etc/zaita/courier/config.yaml
Example 2: Azure Workload Identity — Azure Virtual Machine¶
A Courier running on an Azure virtual machine with a managed identity assigned. No credentials are stored on the host.
api:
base_url: https://au.zaita.com
version: v1
timeout_seconds: 30
verify_tls: true
retries: 3
retry_backoff: 60
auth:
uuid: cour_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
method: azure_jwt
tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
certificate:
output_dir: /etc/ssl/zaita
cert_filename: service-cert
key_filename: service-key
generate_keys_locally: true
key_algorithm: ecdsa
key_size: 384
digest: sha-384
certificate_validity_period: 90
renewal_threshold_days: 30
common_name: "api.example.com"
on_success: "/bin/bash /opt/scripts/reload-service.sh"
on_failure: "/bin/bash /opt/scripts/alert.sh"
logging:
level: info
file: /var/log/zaita-courier.log
Requirements:
- The Azure VM must have a system-assigned or user-assigned managed identity.
- The Zaita machine account must be configured to accept Azure Workload Identity tokens from the specified tenant_id and client_id.
- If using a user-assigned managed identity, ensure the client_id matches the identity assigned to the VM.
Example 3: Azure Arc — On-Premises Server¶
A Courier running on an on-premises server enrolled in Azure Arc. The Arc agent provides the same managed identity metadata endpoint as Azure-hosted VMs, so the configuration is identical to Example 2. No additional Courier configuration is required.
auth:
uuid: cour_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
method: azure_jwt
tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Requirements: - The server must be enrolled in Azure Arc and the Arc agent must be running. - A managed identity must be assigned to the Arc-enabled server in the Azure portal.
Example 4: AWS IAM OIDC — EC2 Instance¶
A Courier running on an AWS EC2 instance with an IAM instance profile attached.
api:
base_url: https://au.zaita.com
version: v1
timeout_seconds: 30
verify_tls: true
retries: 3
retry_backoff: 60
auth:
uuid: cour_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
method: aws_oidc
role_arn: arn:aws:iam::123456789012:role/ZaitaCourierRole
region: ap-southeast-2
certificate:
output_dir: /etc/ssl/zaita
cert_filename: service-cert
key_filename: service-key
generate_keys_locally: true
key_algorithm: ecdsa
key_size: 384
digest: sha-384
certificate_validity_period: 90
renewal_threshold_days: 30
common_name: "service.example.com"
on_success: "/bin/bash /opt/scripts/reload-service.sh"
on_failure: "/bin/bash /opt/scripts/alert.sh"
logging:
level: info
file: /var/log/zaita-courier.log
Requirements:
- The EC2 instance must have an IAM instance profile attached with permission to assume ZaitaCourierRole.
- The IAM role's trust policy must allow the EC2 service or the specific instance profile to assume it.
- The Zaita machine account must be configured to accept AWS IAM OIDC tokens from the specified role ARN.
Example 5: SPIFFE / SPIRE¶
A Courier running in an environment with a SPIRE agent deployed. The Courier obtains its identity from the local SPIRE workload API at runtime.
api:
base_url: https://au.zaita.com
version: v1
timeout_seconds: 30
verify_tls: true
retries: 3
retry_backoff: 60
auth:
uuid: cour_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
method: spiffe
workload_api_socket: unix:///tmp/spire-agent/public/api.sock
certificate:
output_dir: /etc/ssl/zaita
cert_filename: service-cert
key_filename: service-key
generate_keys_locally: true
key_algorithm: ecdsa
key_size: 384
digest: sha-384
certificate_validity_period: 90
renewal_threshold_days: 30
common_name: "service.example.com"
on_success: "/bin/bash /opt/scripts/reload-service.sh"
on_failure: "/bin/bash /opt/scripts/alert.sh"
logging:
level: info
file: /var/log/zaita-courier.log
Requirements:
- A SPIRE agent must be running on the host and accessible at the configured workload_api_socket path.
- The SPIRE server must be configured with a registration entry that matches the workload running the Courier.
- The Courier process user must have read access to the workload API socket.
- The Zaita machine account must be configured to accept SPIFFE/SPIRE identity.
Example 6: Windows — Microsoft IIS¶
A Courier running as a Windows Scheduled Task under a Group Managed Service Account (gMSA), renewing a certificate bound to an IIS site.
api:
base_url: https://au.zaita.com
version: v1
timeout_seconds: 30
verify_tls: true
retries: 3
retry_backoff: 60
auth:
uuid: cour_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
method: client_secret
client_id: ${ZAITA_CLIENT_ID}
client_secret: ${ZAITA_CLIENT_SECRET}
certificate:
output_dir: C:\ProgramData\Zaita\Certs
cert_filename: iis-cert
key_filename: iis-key
generate_keys_locally: true
key_algorithm: rsa
key_size: 4096
digest: sha-256
certificate_validity_period: 365
renewal_threshold_days: 60
common_name: "www.example.com"
subject_alternative_names: "example.com"
organization: "Example Org"
country: "AU"
key_usage: "Digital Signature, Key Encipherment"
extended_key_usage: "Server Authentication"
on_success: "powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\Update-IISBinding.ps1"
on_failure: "powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\Alert-CertFailure.ps1"
logging:
level: info
file: C:\ProgramData\Zaita\Logs\courier.log
Requirements:
- The gMSA must have write access to the output_dir.
- The gMSA must have permissions to write to the Windows certificate store, update IIS bindings, and restart IIS.
- RSA is used here for broad IIS compatibility. ECDSA P-384 can be used on Windows Server 2019 and later with IIS 10+.
Example 7: CI/CD Pipeline — GitHub Actions¶
A Courier invoked within a GitHub Actions workflow using OIDC token federation. No secrets are stored in the repository or pipeline configuration.
Note: This example requires the Zaita machine account to be configured for OIDC federation with your GitHub organisation and repository.
# .github/workflows/renew-cert.yml
name: Renew Certificate
on:
schedule:
- cron: '0 */12 * * *'
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
renew:
runs-on: self-hosted
steps:
- name: Run Zaita Courier
env:
ZAITA_CLIENT_ID: ${{ vars.ZAITA_CLIENT_ID }}
ZAITA_CLIENT_SECRET: ${{ secrets.ZAITA_CLIENT_SECRET }}
run: |
zaita-courier generate -c /etc/zaita/courier/config.yaml
For pipeline environments that support OIDC token issuance, replace the Client ID/Secret auth with the appropriate federated identity method (Azure, AWS, or SPIFFE) to eliminate stored secrets entirely.