Skip to content

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 AdminSettings. 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.