Courier Best Practices¶
Network Design¶
Route Couriers Through a Bridge¶
In production environments, configure Couriers to connect via a Bridge rather than directly to the Zaita SaaS. This restricts Courier hosts to LAN-only communication — no direct internet access is required. The Bridge serves as the single controlled egress point for all platform traffic.
api:
base_url: https://<bridge-host>
verify_tls: true
See Bridges — Best Practices for network topology guidance.
Always Verify TLS¶
Keep verify_tls: true in all production configurations. Only disable TLS verification in isolated development environments with self-signed certificates. Never disable it when connecting to the Zaita SaaS control plane.
Authentication¶
Prefer Credential-less Authentication¶
Use SPIFFE/SPIRE, Azure Workload Identity, or AWS IAM OIDC wherever possible. These methods issue short-lived tokens at runtime — no credentials are stored on the host, there is nothing to rotate, and there is no risk of credential leakage. See Authentication for configuration details.
Disable Unused Legacy Methods¶
If your organisation does not use X.509 certificate or Client ID/Secret authentication, disable them globally under Admin → Settings. This prevents legacy methods from being used even if a machine account is misconfigured or compromised.
Use Dedicated Machine Accounts¶
Create a separate machine account for each Courier deployment rather than sharing one across multiple hosts. Dedicated accounts simplify auditing, enable targeted revocation, and make IP whitelisting practical.
Key Generation¶
Generate Keys Locally¶
Set generate_keys_locally: true to ensure private keys are created on the target system and never transmitted to the platform. This follows the principle that a private key should never leave the system where it will be used.
certificate:
generate_keys_locally: true
When local key generation is not possible, the platform's back control plane generates the key and encrypts it before delivery. See Architecture for details on how private key material is protected in transit.
Use Strong Cryptographic Parameters¶
| Algorithm | Minimum Recommended | Notes |
|---|---|---|
| RSA | 4096 bits | Use where legacy compatibility is required |
| ECDSA | P-384 (384-bit) | Recommended default for modern deployments |
| Digest | SHA-384 | Use SHA-512 for high-security environments |
Avoid SHA-256 and RSA 2048 for certificates with long validity periods or in high-security environments.
Certificate Lifecycle¶
Set a Meaningful Renewal Threshold¶
Configure renewal_threshold_days to ensure the Courier attempts renewal well before a certificate expires. A threshold of 30 days is a reasonable baseline; increase to 60–90 days for critical systems to allow time to investigate and resolve any renewal failures.
certificate:
renewal_threshold_days: 30
Always Configure On-Success and On-Failure Hooks¶
The on_success script handles certificate installation and service restarts after a successful renewal. Without it, the new certificate is written to disk but the running service continues to use the old one.
The on_failure script should notify your monitoring or alerting system so that renewal failures are surfaced promptly — before they become expired certificate incidents.
certificate:
on_success: "/bin/bash /opt/scripts/restart-nginx.sh"
on_failure: "/bin/bash /opt/scripts/alert-cert-failure.sh"
Scheduling¶
Schedule Every 12 Hours¶
Schedule the Courier to run every 12 hours. The vast majority of runs will result in no action — the Courier checks the certificate status and exits immediately if no renewal is needed. The performance impact is negligible.
More frequent scheduling reduces the window between a renewal failure and detection, but is rarely necessary. Less frequent scheduling increases the risk of missing a renewal window.
Use a Least-Privilege Service Account¶
On Linux, run the Courier as a dedicated system account with access restricted to the certificate output directory and any scripts it needs to execute. On Windows, use a Group Managed Service Account (gMSA) with only the permissions required for certificate installation and service management.
Operations¶
Validate Configuration Before Deployment¶
Always run validate-config before deploying a new or modified configuration to production. It catches syntax errors and invalid settings without touching the live certificate or making any API calls:
zaita-courier validate-config -c config.yaml
Verify Connectivity and Authentication First¶
When setting up a new Courier deployment, use the diagnostic commands to confirm connectivity and authentication before running the full workflow:
zaita-courier check-api-health -c config.yaml
zaita-courier check-api-auth -c config.yaml
Enable File-Based Logging in Production¶
Configure a log file for all production Courier deployments. Logs provide an audit trail of certificate operations and are essential for diagnosing renewal failures:
logging:
level: info
file: /var/log/zaita-courier.log
Configure Retries for Transient Failures¶
Set retries to at least 3 with a retry_backoff of 60–120 seconds to handle transient network issues without overwhelming the API:
api:
retries: 3
retry_backoff: 60
CI/CD Pipeline Integration¶
The Courier is well-suited to CI/CD pipeline integration, particularly where the pipeline platform provides a federated identity capability. Pipelines on GitHub Actions, GitLab CI, Azure DevOps, and similar platforms can issue OIDC tokens that the Courier uses for credential-less authentication — no secrets need to be stored in the pipeline configuration.
Configure the Courier to run as a pipeline step with the appropriate federated identity method. See Examples and Tutorials for worked examples.