Skip to main content

Quick Start: Trust a TLS Inspection Certificate

Configure StratoLens to trust the certificate authority used by your corporate proxy, firewall, or SSL-inspection appliance. This is an advanced configuration, and only necessary if you wish to SSL inspect StratoLens traffic.

StratoLens runs on Node.js, which uses its own built-in certificate list and ignores the container's operating-system trust store. Adding your CA to the OS store has no effect: the certificate must be mounted as a file and pointed to with an environment variable.

1Prepare the certificate chain

You need your internal root CA certificate, plus every intermediate between it and the certificate your proxy signs with. If you're unsure what your proxy presents, run this from a machine behind the same proxy:

Bash (machine behind the proxy)
openssl s_client -showcerts -connect management.azure.com:443 -servername management.azure.com </dev/null

Concatenate all of them into one PEM file. Order doesn't matter, because Node.js reads every certificate in the file:

Bash
cat internal-root-ca.pem internal-issuing-ca.pem > stratolens-proxy-ca.pem

The root is the part that matters

Node.js only trusts a chain that terminates in a self-signed root present in this file. An intermediate alone is never enough, no matter what your proxy sends. Adding the intermediates as well is optional if your appliance presents its full chain, and harmless if it does: Node.js won't fetch a missing intermediate the way a browser does, so a self-contained file works either way.

2Store the certificate in Key Vault

Open the Key Vault deployed with StratoLens (kv-{company}-{id}), then Objects → Secrets → Generate/Import.

  • Name: stratolens-proxy-ca
  • Secret value: paste the full contents of your PEM file
Key Vault → ObjectsSecrets. The expected state after saving: stratolens-proxy-ca listed and Enabled, next to the secrets StratoLens deployed.

After saving, reopen the secret and click Show Secret Value. Confirm that -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- appear on their own lines.

If the line breaks were lost, the certificate will not work

Some browsers and clipboards flatten the newlines out of a pasted PEM. If the value doesn't look right, upload it from Azure Cloud Shell instead:

Azure CLI (Bash / Cloud Shell)
az keyvault secret set \
  --vault-name <KEY_VAULT_NAME> \
  --name stratolens-proxy-ca \
  --file stratolens-proxy-ca.pem

Replace <KEY_VAULT_NAME> with the name of your vault.

Permissions

You may need the Key Vault Secrets Officer role to write secrets. The StratoLens managed identity already has read access, so no additional permissions are needed for it.

While you have the secret open, copy its Secret Identifier. Step 3 needs it.

The secret version page. The Secret Identifier is the URL step 3 asks for, but note the trailing version id.

Drop the version id from the URL

The identifier the portal copies ends in a version GUID: …/secrets/stratolens-proxy-ca/<version>. Delete that last segment so the reference reads …/secrets/stratolens-proxy-ca. A versioned URL pins the Container App to the certificate you uploaded today, so a future PKI rotation (see Maintenance) would silently keep serving the old one.

3Add the secret to the Container App and the scheduler job

On the Container App (ca-{company}-stratolens), go to Settings → Secrets → Add.

  • Key: proxy-ca
  • Type: Key Vault reference
  • Key Vault secret URL: https://<KEY_VAULT_NAME>.vault.azure.net/secrets/stratolens-proxy-ca
  • Identity: pick id-{company}-stratolens-scanner from the dropdown
Container App → SettingsSecrets. The proxy-ca key as a Key Vault reference, resolved by the StratoLens scanner identity.

Repeat the identical steps on the scheduler job (job-{company}-stratolens) under Settings → Secrets.

The scheduler job's Secrets blade. Identical key, URL, and identity: the job keeps its own copy of the secret.

The portal accepts either a versioned or an unversioned Key Vault URL here. Use the unversioned form, for the reason given in step 2.

The secret key becomes the filename

Name it exactly proxy-ca. It will be mounted as the file /etc/ssl/extra/proxy-ca, which the next step references. Certificate files don't need a .crt extension: Node.js identifies PEM files by their contents.

4Mount the certificate on the Container App

First, go to Application → Volumes and click Add:

  • Volume name: ca-certs
  • Volume type: Secret
  • Mount all secrets: leave this checked

Click Save as new revision to commit the volume before moving on.

Container App → Volumes. A Secret volume named ca-certs, before it is mounted into the container.

Then go to Application → Containers → Volume mounts, with the stratolens container selected, and click Add:

  • Volume name: ca-certs
  • Mount path: /etc/ssl/extra
  • Sub path: leave empty

Click Save as new revision again to commit the mount.

ContainersVolume mounts for the stratolens container.

Switch to the Environment variables tab and click Add:

  • Name: NODE_EXTRA_CA_CERTS
  • Source: Manual entry
  • Value: /etc/ssl/extra/proxy-ca

Click Save as new revision once more to deploy the change.

The same container → Environment variables. NODE_EXTRA_CA_CERTS is appended to the variables StratoLens already ships with. Values are redacted here; yours will be populated.

Add to the existing list, don't replace it

Add the environment variable alongside the entries already there. Don't modify or remove them.

Don't mount at /etc/ssl/certs

That path holds the container's existing certificate store, and mounting over it will hide certificates the platform needs.

5Mount the certificate on the scheduler job

Open the scheduler job (job-{company}-stratolens) and repeat step 4 against the container named scheduler. The values are identical; only the blade locations differ. On a job they live under Settings rather than Application.

First, go to Settings → Volumes and click Add:

  • Volume name: ca-certs
  • Volume type: Secret
  • Mount all secrets: leave this checked

Click Apply to commit the volume before moving on.

The job's Volumes tab. The no associated mounts banner is expected at this point: it clears once you add the mount on the scheduler container.

Then go to Settings → Containers, select the scheduler container, click Edit, and on the Volume mounts tab click Add:

  • Volume name: ca-certs
  • Mount path: /etc/ssl/extra
  • Sub path: leave empty

Click Apply again to commit the mount.

The job's Containers blade. Select the scheduler container, click Edit, then set the same mount on its Volume mounts tab.

Switch to the Environment variables tab and click Add:

  • Name: NODE_EXTRA_CA_CERTS
  • Source: Manual entry
  • Value: /etc/ssl/extra/proxy-ca

Click Apply once more to deploy the change.

The scheduler container → Environment variables. The same variable and value as the Container App.

Finish with Apply, not just Save

Saving an edit only closes the panel. The job isn't updated until you click Apply at the bottom of the Edit and deploy screen. Leaving without it discards the volume and the environment variable, and the portal gives no warning.

Don't skip this step

If only the web app is configured, StratoLens loads normally and every scan fails. The two containers have separate configurations.

6Verify (optional)

This step is optional. It confirms the change from inside the container, which is worth doing if scans still fail after step 5, and skippable if they already succeed.

Wait for the new revision to reach Running, then open a shell in the stratolens container. Either the portal (Monitoring → Console, pick the container, start a session) or the Azure CLI works:

Azure CLI (Bash / Cloud Shell)
az containerapp exec -g <RESOURCE_GROUP> -n <CONTAINER_APP_NAME> --command sh

Replace <RESOURCE_GROUP> and <CONTAINER_APP_NAME> with your resource group and the Container App name (ca-{company}-stratolens).

Two checks confirm the change: the certificate is where you mounted it, and Node.js actually trusts it. First, confirm the file arrived:

Container App shell
ls -l /etc/ssl/extra/

proxy-ca should be listed, alongside the other secrets the volume mounts. Print it to confirm the contents survived the trip through Key Vault:

Container App shell
cat /etc/ssl/extra/proxy-ca

You should see your PEM, with -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- each on their own line, once per certificate in the chain. If the markers and the base64 body run together on one line, the newlines were lost when the secret was pasted: return to step 2 and upload the file from Cloud Shell instead.

Then confirm Node.js trusts the chain, using the same trust store the scanner uses:

Container App shell
node -e "require('https').get('https://management.azure.com/', r => { console.log('OK', r.statusCode); process.exit(0) }).on('error', e => { console.log('FAIL', e.code); process.exit(1) })"
  • OK followed by a status code — success. OK 400 and OK 401 are both normal: an unauthenticated request to the ARM root is expected to be rejected. The code doesn't matter, only that the TLS handshake completed.
  • FAIL followed by a certificate error — the chain still isn't trusted. See Troubleshooting below.

The scheduler job has no console of its own while it is idle, so verify it by running a scan: open StratoLens, start a scan, and confirm it completes instead of failing on certificate errors.

StratoLens trusts your CA

The web app and the scheduler job both reach Azure through your inspecting proxy. Keep the Key Vault secret current when your PKI rotates (see Maintenance).

Troubleshooting

  • FAIL UNABLE_TO_VERIFY_LEAF_SIGNATURE or FAIL SELF_SIGNED_CERT_IN_CHAIN — the chain in your PEM file is incomplete. You're most likely missing the root CA or an intermediate. Return to step 1.
  • The ls command doesn't show the file — the volume mount or secret name doesn't match. Check that the secret key is exactly proxy-ca and the mount path is exactly /etc/ssl/extra.
  • Nothing changed at all — verify the value of NODE_EXTRA_CA_CERTS matches the file exactly. If the path doesn't exist, Node.js logs a startup warning and silently continues with its default certificates, so the original symptom looks unchanged.
  • Scans fail while the UI works — the scheduler job wasn't configured. Repeat step 5.
  • Other secrets appear in /etc/ssl/extra/ — expected. That is what Mount all secrets does: every secret defined on the app becomes a file in the volume. It's harmless, but avoid mounting the folder anywhere sensitive.

Maintenance

When your internal PKI rotates, update the Key Vault secret from step 2 and deploy a new revision. Because you trusted the root CA rather than an intermediate, most rotations require no action at all.

Where to next