Own Infrastructure

The platform we run our own AI on

Every other case here describes work done for somebody else. This one describes the platform Core Purpose Tech runs its own products and its own inference on, which makes us the client and removes the usual reason to be vague.

The components are ordinary: a Kubernetes cluster on hardware we own, a handful of product applications, a Postgres operator, block storage, an ingress layer, and an inference tier serving open-weight models on local GPUs. The list is not the interesting part. What is worth writing down is that the desired state of all of it lives in one Git repository, and that the cluster is reconciled towards that state continuously rather than changed by whoever last had a terminal open.

That distinction decides what an organisation can say about itself. A platform assembled by hand can be described from memory; a reconciled one can be described from a file, and the difference shows up the first time somebody asks what is running and why.

This case describes the operating model and the parts of it that are not yet true. It withholds host names, addresses, credential paths and the ingress map. An operating model transfers to a reader; an inventory only helps somebody looking for a way in.

GitOps operating modelOn-premises KubernetesSelf-hosted open-weight inferenceSecrets managementPromotion and release control
Scroll to see how it works

The Problem

A platform nobody can describe from a file

None of this is unusual, and none of it announces itself. A platform degrades into folklore one convenient shortcut at a time.

Each application arrives with its own idea of how it is deployed. One has a pipeline that applies manifests directly, one is a Helm command somebody keeps in their shell history, one was set up during an evening and works. Nothing is wrong until something has to change, and then the question of what is actually running has no answer that does not begin with logging into the cluster and looking.

Secrets are the sharpest version of the same problem. They are created out of band because they cannot go in Git in the clear, so the one thing that must never be lost is the one thing with no record. Rotating a credential means finding every namespace it was typed into.

Then the drift. Somebody patches a live resource to get past an incident at eleven at night, correctly, and the fix exists only in the cluster. The next reconciliation from the repository — or the next fresh deploy — quietly removes it. The environment and the description of the environment have separated, and nothing reports that they have.

For an inference tier this gets worse rather than better. Models are large, slow to load, and pinned to specific GPUs. A deployment that looks healthy the moment it starts can be thirty seconds away from serving anything, and traffic sent in the meantime fails in ways that read like a model problem rather than a rollout problem.

  • Every application deployed a different way, none of them written down
  • The state of the cluster knowable only by inspecting the cluster
  • Secrets created out of band, so the critical values have no record
  • Hand-patched fixes silently reverted by the next sync
  • Model pods sent traffic before they have finished loading

The Solution

One repository, three roots, and one base per application

The structure is deliberately boring. Its value is that a new application is onboarded by adding files rather than by remembering a procedure.

One repository on a single main branch holds three root Applications: shared, test and prod. Shared carries the platform every environment depends on — ingress, certificates, storage, the Postgres operator, the secrets machinery, monitoring, the inference stack. Test and prod each carry their own stateful services and their own product applications. Each root pulls in its children, so adding an application means committing one Application manifest, not running anything.

Every product application has one base and thin overlays per environment. The overlay patches only what genuinely differs: the namespace, the public host, the TLS secret name, and which Postgres service and credential to use. When the same manifests are duplicated per environment instead, the two copies diverge within weeks and the test environment stops predicting anything about production. A base with a four-field patch cannot drift that way.

Each environment has an AppProject that names the repositories it is allowed to deploy from, as an explicit list rather than a wildcard. It is a small piece of configuration that decides something large: a mistaken or compromised source cannot deploy into a trusted namespace just because it can reach the cluster.

Secrets are resolved rather than stored. Twenty-eight ExternalSecrets pull their values from Vault at runtime, so what lives in Git is the reference and the shape, never the value. Nine SealedSecrets remain from the scheme this replaced, and they still work, which is precisely why that migration is not finished.

  • One branch, three root Applications, 48 child Applications underneath them
  • One base per application; overlays patch namespace, host, TLS secret and database
  • AppProjects with explicit repository allowlists rather than wildcards
  • Secret values resolved from Vault at runtime; Git holds the reference
  • Prune and self-heal on, so a hand-patched cluster is corrected rather than trusted

Key Flow

How a commit becomes production, and where a person stands in the way

The gate is not where people usually expect it. It sits before anything is written to the production overlay, not between the overlay and the cluster.

Step 01

The build produces one identity

CI builds a container image tagged with the commit it was built from. Nothing downstream refers to a moving tag, so the artifact that was tested and the artifact that runs are the same object, and saying which commit is in production is a matter of reading a tag rather than reconstructing a release.

Step 02

The test overlay is updated in Git

The pipeline writes the new tag into the test overlay and commits it. This is the only way a change enters an environment. A pipeline that applied manifests to the cluster directly would leave the repository describing something that is no longer true.

Step 03

Test reconciles itself

Argo CD picks up the commit and syncs test automatically, with pruning and self-healing on. Resources removed from Git are removed from the cluster, and a resource edited by hand is put back. The test environment is therefore never a place where an undocumented fix can survive.

Step 04

A person decides whether this becomes production

The pipeline stops and asks: promote this tag to prod? It waits fifteen minutes for an answer and treats silence as no, so an unattended build ends without a release rather than with one. A parameter set at build start can skip the wait for changes that do not warrant it, and it defaults to off — an unremarkable default that decides whether the gate is real.

Step 05

Promotion copies a tested tag, and reconciliation does the rest

Approval writes the same tag into the production overlay. From there production reconciles automatically, exactly as test does. This is the part worth being precise about: the approval governs what is written to the repository, not whether the cluster is allowed to match it. Once the state is in Git, the cluster converging on it is not a second decision.

Step 06

A failed sync backs off, and a bad release rolls back forwards

Retries use finite exponential backoff, because self-heal against a broken revision will otherwise reapply the same failure indefinitely and bury the real error in identical log lines. Recovery is the previous image, never the previous schema: migrations are generated from the models and reviewed, and they are required to be forward-compatible so that rolling an application back never depends on a database downgrade running correctly under load.

Artifact Preview

The platform rules, and what holds each one up

These are the rules the platform actually runs on. Each is stated so it can be disagreed with, and each names the mechanism that enforces it — because a rule held up only by everyone remembering it is a convention, and conventions do not survive an incident at eleven at night.

Platform operating rules — excerptRedacted excerpt

The rule

What it prevents

How it is held

Desired state reaches a cluster only through the repository

A running change whose origin nobody can find

Argo CD reconciles from Git; the two bootstrap exceptions live in one folder so the exception stays countable

A hand-edited resource is corrected, not inherited

An undocumented fix becoming load-bearing and then vanishing

Prune and self-heal enabled on every application in both environments

Promotion to production waits on a person

A merge turning into a release nobody chose

An interactive approval before the production overlay is written, timing out to no after fifteen minutes

A failing sync backs off instead of retrying forever

Self-heal hammering one broken revision and drowning the real error

Finite retry with exponential backoff and a ceiling, set per application

A project names the repositories it may deploy from

A mistaken or compromised source reaching a trusted namespace

Explicit source allowlists on each AppProject, no wildcards

Every model-serving deployment declares all three probes

Traffic sent to a model still loading, and a wedged one never restarted

A written repository rule requiring startup, readiness and liveness probes against the served health endpoint, with windows tuned to model load time

A model is reachable only from the gateway

An application bypassing routing, policy and the record of what was asked

A NetworkPolicy admitting the gateway pods and monitoring, and nothing else

Schema changes go forward only

A rollback that depends on a downgrade running correctly under load

Migrations generated from the models and reviewed; recovery is the previous image

Host names, network addresses, credential paths, repository URLs and the ingress map are withheld. The rules transfer to another organisation; the inventory only helps somebody looking for a way in.

Sovereign AI, Concretely

What the gateway enforces, and why the network enforces it

Our case on sovereign AI describes a gateway architecture for a client we cannot name. This is the same shape, running on our own hardware, where we can say what is in it.

One namespace holds the inference tier: a gateway that presents a single API, open-weight models served on local GPUs behind it, three embedding services, a reranker, a vector database, and the chat interface people actually use. Model deployments are one base with per-model overlays that patch what differs — which weights, which GPU, how much memory, how long to wait for a load. Adding a model is a small file, not a new deployment to maintain.

The part that matters for governance is a NetworkPolicy. Model pods accept connections from the gateway pods and from monitoring, and from nothing else. An application inside the cluster cannot reach a model directly even if someone configures it to, because there is no route. Gateway-only access stops being a rule people follow and becomes a property of the network, which is the difference between a policy and a diagram.

That single control is what makes the rest answerable. Because every request passes one place, routing, rate limits, keys and the record of what was asked have one place to live. Prompts and documents stay inside the cluster by default, and reaching an external provider is a routing decision made deliberately in one file rather than a library import made incidentally in twelve.

It also makes the ordinary economics work. The models are already paid for and the machines are already there, so inference that would otherwise be metered per token is instead a question of whether the GPUs are busy — which is what makes it reasonable to point them at work nobody would fund per-token, such as the deferred defect backlog they chew through overnight.

  • One gateway API in front of locally served open-weight models
  • One vLLM base with per-model overlays for weights, GPU and load window
  • Embeddings, reranking and a vector database in the same namespace
  • Direct model access blocked by NetworkPolicy, not by convention
  • External providers reachable by explicit routing decision, never by default

Honest Limits

What this platform does not do

A case about reconciled infrastructure invites exactly one question: what is not reconciled? These are the answers, and they are the reason this page does not claim GitOps all the way down.

The machines are described, but not reconciled. A node begins as a golden image in the hypervisor, cloned and given its identity — hostname, address, keys — at first boot, deliberately carrying none of that in the image so no clone can inherit another node's identity. It then runs one bootstrap script that takes a role, joins the cluster and prepares its storage. That is a real procedure and it is written down. What it is not is a desired state: it runs once, imperatively, and nothing afterwards notices if a node drifts away from what it was set up to be. The cluster self-heals; the machines under it do not.

That layer also lives outside the repository this case is about, in an older one where it is not yet committed. So the platform has two halves with different disciplines — one reconciled continuously from version control, one scripted and held locally — and the honest description of the second is that it is documented rather than governed. Closing that gap is ongoing work, and this case cannot report it as done.

Two manifests are applied by hand — the load-balancer pieces that must exist before the reconciler has anything to reconcile through. Bootstrap has to start somewhere. They are kept in a single folder so that the exception can be counted and pointed at, rather than dissolving into general practice.

The network is not default-deny. Three NetworkPolicies exist: the model tier and the secrets ingress are fenced, and the rest of the cluster is internally open. Fencing what matters first is a reasonable order of work, but describing that as a segmented network would not be true.

Test and production are separate namespaces with separate databases on the same cluster and the same hardware. They are isolated from each other's mistakes, not from each other's failures. For a platform this size that is a defensible cost decision, and it is a cost decision rather than an architectural one.

The secrets migration is unfinished, and the reason is the ordinary one. Twenty-eight references resolve from Vault; nine sealed secrets from the previous approach remain, and they work. Nothing forces the last nine, so they are still there — which is worth stating plainly, since a platform case that reports only completed migrations is describing a plan rather than a system.

  • Nodes built from a golden image and one bootstrap script — scripted, but never reconciled
  • Two bootstrap manifests applied by hand, kept in one folder
  • Three NetworkPolicies; the cluster is not default-deny
  • One cluster, two environments — isolated by namespace, not by failure domain
  • Nine sealed secrets still outstanding against twenty-eight resolved from Vault

Proof Layer

What was built, under what constraints, and what can be checked

Read on 2026-08-16 from the repository that defines the platform. Counts are what the files say, not what the documentation claims about them.

Context

Operator
Core Purpose Tech, operating its own platform — no client, and therefore no redaction negotiation
Workloads
Four product applications across two environments, plus a shared inference tier
Period
First commit 2026-03-04, 815 commits by 2026-08-15

Scope

Reconciled
48 Argo CD Applications: 37 shared platform components, plus per-environment stateful services and product applications
Environments
Shared, test and prod as three root Applications on one branch
Inference
A gateway, locally served open-weight models, three embedding services, a reranker and a vector database

Constraints

Hardware
Fixed on-premises capacity, including a bounded number of GPUs, so model placement is explicit rather than scheduled freely
Team
Operated alongside client delivery, which rules out any control that depends on someone being available to perform it
Data
Prompts and documents stay in the cluster unless a routing decision deliberately sends them elsewhere

Artifacts Delivered

Repository
Root Applications, AppProjects with explicit source allowlists, namespaces, and one base plus overlays per application
Operating rules
A committed rules file requiring probes on model-serving deployments and forward-only schema changes
Runbooks
Onboarding, secrets, GPU setup, an observability contract for new services, and a Postgres restore written from one that was performed

Outcome Signals

Answerable state
What runs in either environment is read from the repository rather than from the cluster
Release control
Production is entered by an approval that times out to no, and left by rolling an image back
Enforced routing
No workload can reach a model except through the gateway, as a property of the network
Stated gaps
The unreconciled hypervisor, the two manual manifests, the open internal network and nine outstanding sealed secrets are named rather than implied

Outcome signals are anonymized measurements from a defined pilot period. Ranges are used to preserve client confidentiality. The measurement period, baseline, and scope are stated in the classification and evidence note on this page.

How to read this case

Classification and evidence method

A system we run for ourselves. Nothing here is a client outcome, and no adoption is claimed — but we are the client, so it can be described in detail an engagement would not permit.

No controlled before-and-after study was run, so this case states no improvement percentages. What it reports instead is verifiable: what the system does, what it refuses to do, and what it does not cover. This case reports properties of a platform we operate, not an improvement over a measured baseline, because there is no controlled before-and-after to report. The verifiable facts are the repository's own, read on 2026-08-16: 815 commits between 2026-03-04 and 2026-08-15; 48 Argo CD Application manifests; 37 shared platform components; 28 ExternalSecrets against 9 remaining SealedSecrets; 3 NetworkPolicies. The section on what this platform does not do is drawn from the same reading, and the counts there are the honest ones.

Case type
Own Infrastructure
Number basis
Not measured — capability stated instead

Published · Updated

Read the sovereign AI case: The same architecture, delivered for a client
Related Case
Sovereign AIClient deliveryGateway architecture

The same architecture, delivered for a client

The sovereign AI gateway case describes this shape as delivered into a regulated organisation, where the identity is confidential and the inventory could not be shown. Read together, one supplies the reasoning and this one supplies the concrete platform underneath it.

Read the sovereign AI case

explore further

Related capabilities

  • Platform Engineering

    Reliable and maintainable platform foundations that support development and operations at scale.

  • Operational AI

    AI systems that integrate with existing platforms and workflows, with control, traceability, and operational reliability.

Further reading

  • What sovereign AI actually means

    The term covers four separable properties, and vendors tend to sell the cheapest one. Which of them you actually need depends on what you are protecting against.

  • On-premises vs hosted LLM: how to choose

    The choice is usually settled by data residency and contracts, not by cost or model quality. Here is what each option costs you in practice.

  • Bugs fixed overnight, reviewed in the morning

    We built an in-house service that works the backlog of small, deferred defects while the office is empty, using computing capacity the organisation has already paid for. What makes it usable is not the model. It is the narrow scope, the team's own tests, and the review queue waiting at 08:00. The more interesting property is that the loop from report to released fix can close — which makes autonomy a decision about which changes you trust, rather than an engineering leap.

Interested in how this approach could work for your organization?

Get in touch
core purpose. techTechnology consulting with purpose.