not.bot Verify: Preflight Checklist

Updated

not.bot™ Verify: Pre-flight ChecklistPermalink to not.bot™ Verify: Pre-flight Checklist

Complete every item before you open the Deployment Checklist. Missing prerequisites cause most first-deploy failures.


InfrastructurePermalink to Infrastructure

# Requirement How to verify Done
1 Kubernetes cluster with a configured kubectl context kubectl cluster-info returns a running control plane
2 Helm 3 installed helm version shows v3.x
3 helm-diff plugin installed helm plugin list includes diff
4 PostgreSQL 14 or later, reachable from inside the cluster kubectl run pgcheck --rm -i --restart=Never --image=postgres:16 -- pg_isready -h <HOST> -p 5432 reports "accepting connections"
5 Keycloak 22 or later, served at a public HTTPS hostname and reachable from inside the cluster at that same hostname kubectl run kccheck --rm -i --restart=Never --image=curlimages/curl -- curl -fsS -o /dev/null -w "%{http_code}" https://<KEYCLOAK_PUBLIC_HOSTNAME>/realms/master prints 200 — see the note below if Keycloak uses a private CA
6 A container registry your cluster can pull from docker pull <YOUR_REGISTRY>/any-existing-image succeeds
7 Cluster supports internal LoadBalancer Services Managed K8s (EKS/GKE/AKS) supports this by default. On bare-metal, kubectl get pods -n metallb-system shows running pods

Items 4 and 5 say from inside the cluster deliberately: run the probe as a pod, not from a host shell. Host-level reachability does not imply pod reachability (a database bound to 127.0.0.1, or a docker proxy on the host, passes a host probe and fails every pod).

Use the public hostname operators will log in at in item 5, not an internal service address. Keycloak stamps that hostname into every token it issues, and the admin service checks it (Deployment Checklist §5.1), so the admin pod has to reach Keycloak by that name.

Item 5 fails in two different ways and they need different fixes, so read the failure rather than just the missing 200 (curl -fsS prints 000 for both). A TLS/certificate error (SSL certificate problem, unable to get local issuer certificate) means the probe reached Keycloak but does not trust its CA. A timeout or connection refusal means the pod could not reach the hostname at all; if it resolves to an address the cluster cannot hairpin to (AWS EC2 Elastic IPs are the common case), you need an in-cluster DNS override before deploying — Deployment Checklist Appendix B §B.12.

If Keycloak uses a private CA, this probe cannot print 200 on its own — it carries no CA, so it will always report a certificate error. That is expected, and it tells you that you will need the admin chart's extraCaCerts values. Two ways to satisfy this item instead: re-run with -k to confirm the endpoint is otherwise healthy (a 200 with -k means reachability and DNS are fine and only trust is missing), or run the Deployment Checklist §B.12 preflight probe, which mounts a CA into the probe pod and checks reachability and trust together — substitute the path to your own CA certificate for the one shown there. Prefer the §B.12 probe: it is the same check the admin pod will make.

Workstation toolsPermalink to Workstation tools

# Requirement How to verify Done
8 openssl openssl version returns a version
9 OpenBao CLI (bao) installed bao --version returns a version

If you intend to rebuild the OpenBao image from source for supply-chain validation, also install Docker with buildx. See Deployment Checklist Appendix A. The mainline flow uses the pre-built image shipped in the chart and requires no compiler toolchain.

AccessPermalink to Access

# Requirement How to verify Done
10 DNS control for the domain in your deployment-config.json You can add a TXT record at the root of that domain
11 DNS control for the internal zone holding your admin service hostname You can add a CNAME for Decision H in that zone
12 Permission to create namespaces in the Kubernetes cluster kubectl auth can-i create namespaces returns yes
13 Permission to create secrets in the Kubernetes cluster kubectl auth can-i create secrets returns yes

Deployment packagePermalink to Deployment package

# Requirement How to verify Done
14 deployment-config.json from your welcome email File contains your customerId, organizationName, apiKey, billingServerUrl, and domain
15 not.bot_verify_deployment.zip from your welcome email Unzips to a helm/ directory with three subdirectories: admin-service, openBao, signer-service

Decisions to make before you startPermalink to Decisions to make before you start

You will need these values during deployment. Decide on them now so you are not stopping mid-checklist.

# Decision Your value
A Kubernetes namespace for OpenBao _______________
B Kubernetes namespace for the admin service _______________
C Kubernetes namespace for signature servers _______________
D OpenBao namespace name (internal to OpenBao, not Kubernetes) _______________
E1 PostgreSQL database name for the admin service _______________
E2 PostgreSQL database name for the signature server — must be a different database from E1 _______________
F PostgreSQL admin service user — name (default notbot_admin) and password. Owns database E1. name: _______________ password: _______________
G1 PostgreSQL signature server user — name (default notbot_signer) and password. Owns database E2. name: _______________ password: _______________
G2 PostgreSQL read-only user — name (default notbot_signer_reader) and password. Lets the admin service read verification counts from E2. name: _______________ password: _______________
H Internal hostname operators use to reach the admin UI (e.g. admin.internal.example.com) _______________
I Internal hostname for the signature server load balancer (e.g. signer.internal.example.com) _______________
J TLS certificate for the admin LB (cloud-managed cert ARN/resource ID, or path to BYO cert + key) _______________
K TLS certificate for the signature server LB (Decision I's hostname). May be the same multi-SAN cert as Decision J or a separate cert. _______________

Decision H appears in Keycloak redirects, Helm values, and your internal DNS zone. Decision I appears in Helm values, your internal DNS zone, and the SDK configuration. Use the exact same value everywhere each one appears.

not.bot Verify uses two PostgreSQL databases, because the admin service and the signature server each create and migrate their own schema. Database E1 belongs to the admin service, database E2 belongs to the signature server, and each is owned by its own user. The admin service also reads verification counts out of E2 for the dashboard and for usage reporting, which is what the read-only user G2 is for. Both databases can live on the same PostgreSQL instance; you will need an account there that can create databases and roles.


If any item above is incomplete, resolve it before proceeding. The Deployment Checklist assumes all of these are in place.