Verify the installation
Run these after the install and after every upgrade. Each check says what a pass looks like. The last one, NetworkPolicy, is the one a clean install cannot prove on its own.
The platform is up
Section titled “The platform is up”On an operator install, the resource reports every component available:
kubectl -n olympus get olympuses.olympus.olympusx.ai olympus# NAME VERSION COMPONENTS READY AGE# olympus 1.1.0 11/11 True 20mThe denominator is however many components your resource turns on: nine with neither the identity service nor the guardrails service, eleven with both.
On either path:
kubectl -n olympus get podskubectl -n olympus rollout status deploy/olympus-control-planekubectl -n olympus rollout status deploy/olympus-gatewayEvery pod is Running and Ready, and both rollouts report successfully rolled out.
The schema is applied
Section titled “The schema is applied”kubectl -n olympus logs deploy/olympus-control-plane -c migrate | tail -3# {"time":"…","level":"INFO","msg":"migrations complete","applied":…,"already_applied":…}Several pods run the same migration step and exactly one applies the schema, so one pod reports a count under applied and the others under already_applied. Either line means the schema is current. The control plane reports not ready until the schema matches its version.
The console answers, and reaches the control plane
Section titled “The console answers, and reaches the control plane”kubectl -n olympus port-forward svc/olympus-studio 8080:8080In a second terminal:
curl -s localhost:8080/api/v1/ping# {"env":"prod","pong":"olympus"}The request goes to the console, which forwards /api/ to the control plane, so the answer proves both and the link between them.
Through the published hostname, the console sends its security headers:
curl -sI https://<console-host>/ | grep -i -E 'strict-transport|content-security'# strict-transport-security: max-age=31536000; includeSubDomains# content-security-policy: default-src 'self'; script-src 'self' 'sha256-…'; …The policy names the identity provider’s origin for sign-in, derived from the issuer, and forbids framing the console. If curl rejects the certificate, this machine does not trust it, and browsers that do not trust it will warn the same way.
The control plane is ready
Section titled “The control plane is ready”kubectl get --raw /api/v1/namespaces/olympus/services/olympus-control-plane:http/proxy/readyz# {"status":"ready"}The gateway enforces authentication
Section titled “The gateway enforces authentication”curl -s https://<gateway-host>/v1/chat/completions \ -H 'content-type: application/json' -d '{"model":"x","messages":[]}'# {"error":{"message":"provide an Olympus API key as x-api-key or Authorization: Bearer","type":"authentication_error","code":"missing_credentials","param":null}}A refusal naming the missing key is the pass. A 404 on every request means the gateway has not received its configuration from the control plane (Troubleshooting).
Sign-in works
Section titled “Sign-in works”Open https://<console-host> and sign in (First sign-in). If nobody can sign in while every component is healthy, the issuer is wrong or unreachable:
kubectl -n olympus logs deploy/olympus-control-plane | grep -i "identity provider"identity provider not reachable yet means the control plane cannot fetch the issuer’s discovery document.
Invitations arrive
Section titled “Invitations arrive”Invite yourself to a tenant (First sign-in). The console says Invitation sent, and an email titled “Your Olympusx AI account is ready” arrives from the sender address you configured, with a link on <console-host>.
The guardrails service is ready
Section titled “The guardrails service is ready”If you turned it on:
kubectl -n olympus rollout status deploy/olympus-guardrails# deployment "olympus-guardrails" successfully rolled outIn the console, Infrastructure › System health shows Guardrails as Healthy. If you left it off, the control plane’s log opens with GUARDRAILS ARE DISABLED: prompts and completions pass through uninspected. In an environment carrying customer data, that line is a finding.
Metrics are scraped
Section titled “Metrics are scraped”If you turned monitoring on:
kubectl -n olympus get servicemonitorTwo ServiceMonitors exist. Then confirm in Prometheus that their targets are up: an object that exists proves nothing about scraping. No targets almost always means a selector label (Configuration). On OpenShift, a cluster administrator must have turned on user-workload monitoring.
NetworkPolicy is enforced
Section titled “NetworkPolicy is enforced”The control plane’s internal listeners have no authentication by design; a NetworkPolicy admits only the gateway’s pods. Whether that policy does anything depends on your CNI, and the API server accepts it either way. Measure it.
Probe a closed port from a pod that is not the gateway:
kubectl -n olympus run probe --rm -i --restart=Never --image=curlimages/curl:8.10.1 -- \ curl -s -o /dev/null -w '%{http_code}\n' --max-time 6 \ http://olympus-control-plane:8084/internal/authorize# 000Then show the same probe works where the policy leaves the port open:
kubectl -n olympus run probe --rm -i --restart=Never --image=curlimages/curl:8.10.1 -- \ curl -s -o /dev/null -w '%{http_code}\n' --max-time 6 \ http://olympus-control-plane:8080/healthz# 200Read the pair together:
- Any HTTP status on the first probe (
200,400,401) is conclusive and bad: the policy is not enforced, and the internal ports are open to everything in the namespace. 000on the first and200on the second is enforcement.000on both means the probe never worked (DNS, scheduling, the image), and you have learned nothing.
Any image with curl works; on an air-gapped cluster, use one from your mirror.
From a tenant’s project namespace, connections to these should time out rather than connect:
| From a tenant namespace, to | Expect |
|---|---|
The control plane’s internal ports 8083, 8084, 8085 |
Timeout |
The control plane’s metrics port 8086 |
Timeout, unless the namespace is an allowed scraper |
The platform database on 5432 |
Timeout |
| The guardrails service, document converter, object store and tracing store | Timeout |
The gateway on 10000 |
Connects: it is the inference API |
A refusal (connection refused) means nothing was listening and proves nothing; a timeout is the policy dropping the packet. Record the results. If your CNI does not enforce policy, record that in your risk register rather than assuming the chart protected you.