OCI WAF Certificates — Renew · Deploy · Verify conceptual editorial illustration

OCI WAF Certificate Renewal: Certbot, OCI CLI and Deployment Checks

OCI WAF · Edge policies (WAAS)
Renew. Deploy. Verify.
Two certificate locations. Two checks.
Server certificate
Certbot renews it when a renewal is due and domain validation succeeds.
WAF Edge-policy certificate
A separately uploaded certificate. Server renewal alone does not replace it.
A successful renewal is the start of deployment, not proof that WAF is updated.
  1. 1 · Renew successfullyConfirm renewal; a configured deploy hook can run after success.
  2. 2 · Deploy separatelyUpload with OCI CLI and select the intended Edge policy and certificate.
  3. 3 · Verify the resultCheck deployment status and the certificate and expiry served to visitors.
Conceptual workflow, not a verified deployment. Hook configuration, policy selection and deployment checks must be validated for your environment.

OCI WAF (Web Application Firewall) Edge policies (WAAS) use a separately managed certificate when HTTPS is configured. HTTP-to-HTTPS redirection must be enabled in the policy; using WAF alone does not enable it.

Certbot renews the server certificate when a scheduled renewal runs and validation succeeds. A separately uploaded Edge-policy certificate is not replaced by server renewal alone. Check the certificate and expiry status at both deployment points.

This guide describes a certificate-expiry case and an example linking certbot deploy hooks with OCI CLI. The historical account is not evidence that the current environment has been verified. The hook still requires separate validation of error handling, policy selection and asynchronous deployment.

The problem: dual certificate architecture

[Browser] │ ▼ [OCI WAF] ←── WAF SSL cert (manual upload) │ ▼ [Apache Server] ←── Server SSL cert (certbot auto-renew)

Even when certbot renews the server certificate, the WAF certificate remains unchanged. If the WAF cert expires, the site becomes inaccessible — regardless of the server cert status.

⚠️ Real scenario: Server certbot certificate was valid until May 21st, but the WAF certificate was expiring in 2 days (March 22). No deploy hooks, no OCI CLI installed.

Diagnosis

# Server certificate status
sudo certbot certificates
# Expiry Date: 2026-05-21 (VALID: 62 days) ← OK

# Deploy hooks exist?
sudo ls -la /etc/letsencrypt/renewal-hooks/deploy/
# Empty ← No automation

# OCI CLI available?
oci --version 2>/dev/null || echo "OCI CLI not installed"
# Not installed ← Can't call API

WAF certificate status: check in OCI Console → WAF Policies → Policy → Settings → SSL certificate expiration date.

Emergency fix: manual certificate upload

Manual upload scope: This procedure applies only to certificate uploads for OCI WAF Edge Policies (WAAS). Paths below are templates, not real files. Replace CERT_NAME with the verified Certbot certificate name; do not assume it equals the domain. Review this procedure independently of the later renewal hook.
1
Preserve originals and minimize copies
/etc/letsencrypt/live/CERT_NAME/fullchain.pem
/etc/letsencrypt/live/CERT_NAME/privkey.pem

fullchain.pem contains the public server certificate and intermediate chain; privkey.pem is the corresponding secret private key. Certbot's live paths track renewed files. Do not weaken ownership or permissions on originals or archive files, or delete originals, to enable a manual upload.

Skip server staging if an existing approved and verified transfer method can safely read the originals with administrator privileges. Ordinary SFTP/scp does not automatically gain sudo privileges. If staging is necessary, create a new dedicated directory outside synchronization, backups and web serving, accessible only to the approved transfer account: directory 0700, both copied files 0600 from creation. Parent paths must be trusted; do not overwrite existing files or symbolic links.

/home/TRANSFER_USER/.dih-waf-export-UNIQUE/fullchain.pem
/home/TRANSFER_USER/.dih-waf-export-UNIQUE/privkey.pem

Replace TRANSFER_USER and UNIQUE with the reviewed account and a new per-task name. Limit ownership assignments to these two copied files and their dedicated directory; never use wildcard or recursive changes. Do not create exposed copies and restrict them afterward.

2
Transfer only to a protected PC workspace

First prepare a dedicated folder on a managed, encrypted PC, excluded from synchronization, sharing and backups. On POSIX systems use directory 0700 and files 0600, owned by the authorized local user. On Windows use NTFS ACLs for the authorized user and necessary system administrators, checking inherited broad access. Do not assume Windows/WSL chmod alone restricts Windows access.

/home/LOCAL_USER/.dih-waf-upload-UNIQUE/fullchain.pem
/home/LOCAL_USER/.dih-waf-upload-UNIQUE/privkey.pem

These are POSIX templates; choose a separately reviewed absolute Windows path. Verify the server host key and transfer only these two files over an encrypted connection to their exact destinations. Avoid the current directory, Downloads and OneDrive. Once transfer is confirmed, remove any server staging copies by their two exact paths and then the empty dedicated directory. Keep key contents out of terminal output, clipboard, chat, logs and Git.

3
Supply files only to the approved OCI certificate input

After confirming the target Edge policy and change approval, select fullchain.pem for SSL certificate and privkey.pem for Private key in the Console. Both use PEM; the leaf certificate precedes intermediates. The WAAS input private key cannot be passphrase-protected. Stop if the format or matching pair is uncertain; do not improvise conversion or upload.

Leave Self signed certificate unchecked for Let's Encrypt. Follow the separately approved certificate-change procedure for saving, policy application and result verification. This guidance itself is neither change approval nor evidence of successful deployment.

4
Clean temporary copies after success, failure or cancellation

When the upload attempt ends or work stops, remove the two exact local temporary files and the empty dedicated folder, and confirm no server staging copies remain. Include partial transfers. Certbot originals, archive files and existing OCI certificate resources are not cleanup targets. Check handling of tool-created temporary files, recycle bins and synchronization/backup copies. Ordinary deletion cannot guarantee erasure from SSDs or snapshots, so minimize copies and retention from the outset. Record paths, times and cleanup outcomes without attaching key contents.

Review renewal integration: OCI CLI + certbot deploy hook

Install OCI CLI

# Oracle Linux 8
sudo yum install -y python36-oci-cli
oci --version

Configure OCI CLI

Check for existing config first:

cat ~/.oci/config 2>/dev/null

If missing or authentication fails, run oci setup config. Required values:

FieldWhere to find
User OCIDOCI Console → top-right avatar → My profile → OCID Copy
Tenancy OCIDOCI Console → avatar → Tenancy → OCID Copy
RegionTop-right of console (e.g., ap-chuncheon-1)

Register the generated public key in OCI:

cat ~/.oci/oci_api_key_public.pem
# Copy output → My profile → API keys → Add API key → Paste
💡 API key limit: OCI allows 3 API keys per user. If all 3 slots are taken, delete an unused key first. OCI doesn't show which keys are actively in use — check Audit logs by fingerprint for indirect confirmation.

The deploy hook script

sudo tee /etc/letsencrypt/renewal-hooks/deploy/upload-to-waf.sh << 'SCRIPT'
#!/bin/bash
LOG="/var/log/waf-cert-upload.log"
OCI="/usr/bin/oci --config-file /home/opc/.oci/config"
WAF_ID="<WAF_POLICY_OCID>"

echo "$(date) ==============================" >> "$LOG"
echo "$RENEWED_DOMAINS" | grep -q "yourdomain" || { echo "$(date) Skip" >> "$LOG"; exit 0; }

CERT_PATH="$RENEWED_LINEAGE/fullchain.pem"
KEY_PATH="$RENEWED_LINEAGE/privkey.pem"
COMPARTMENT_ID=$(${OCI} waas waas-policy get \
    --waas-policy-id ${WAF_ID} \
    --query 'data."compartment-id"' --raw-output)

# 1. Create certificate resource
CERT_RESULT=$(${OCI} waas certificate create \
    --compartment-id "$COMPARTMENT_ID" \
    --certificate-data "$(cat ${CERT_PATH})" \
    --private-key-data "$(cat ${KEY_PATH})" \
    --display-name "auto-$(date +%Y%m%d%H%M%S)")

CERT_OCID=$(echo "$CERT_RESULT" | \
    python3 -c "import sys,json; print(json.load(sys.stdin)['data']['id'])")

# 2. Attach to WAF policy
${OCI} waas waas-policy update \
    --waas-policy-id "$WAF_ID" \
    --policy-config "{\"certificateId\":\"${CERT_OCID}\",\"isSniEnabled\":true,\"isHttpsEnabled\":true,\"isHttpsForced\":true,\"tlsProtocols\":[\"TLS_V1_2\",\"TLS_V1_3\"]}" \
    --force >> "$LOG" 2>&1

echo "$(date) Done: $CERT_OCID" >> "$LOG"
SCRIPT

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/upload-to-waf.sh

Gotchas

ErrorCauseFix
certificateData is not validUsing file:// formatUse $(cat file) instead
No such option: --configWAAS API uses different param nameUse --policy-config
Update shows no changeAsync processing (up to 15 min)Check with oci waas work-request get
Verification required: A configured deploy hook can connect successful server renewal to WAF deployment. Confirm the target policy, deployment status and served certificate before treating the workflow as complete.
Scroll to Top