Twenty-two services behind a single gateway, one database per service, and an
event mesh between them. Every boundary on this page is one your reviewer can
inspect on your own hardware.
Verified, not certified — every claim below names the check that produces it.
Identity is derived, never receivedKong strips X-User-ID, X-Tenant-ID and X-Roles. Each service verifies the bearer token itself.
No shared databaseEach service owns its schema and migrations. Integration is events, not table reads.
The shape of the system
22Services behind one gateway20 app services · 2 headless workers
1:1Service to databaseseparate schema · separate migrations
0Identity headers trustedstripped at the boundary, always
RLSTenant isolation in Postgresenforced under a non-owner role
The boundary
One door — and it does not believe what you tell it.
Every client reaches the platform through Kong on port 8000. Kong strips the
identity headers a client might set, and it does not verify the token either.
That second part is deliberate: verification happens inside each service, against
the token, on every request.
sub · 3f2a-9c11tenant · corniche-airroles · operator
The header claimed platform_admin and a different tenant. The verified token
says operator at corniche-air. The service uses the token, because the
header never arrives.
01
Removed, not merely ignored
X-User-ID, X-Tenant-ID and X-Roles are stripped at the gateway, so no service
can receive them from outside. There is no configuration in which a forged
header becomes an identity — the header simply is not there.
02
The gateway is not the authority
Kong routes, rate-limits and terminates TLS. It does not decide who you are.
A gateway that both routes and authenticates becomes a single point of failure
and a single point of trust at the same time.
03
Each service verifies the token itself
HS256 and RS256 with JWKS, in one shared library rather than twenty-two
implementations. User, tenant and roles are derived from verified claims —
never from transport, never from a trusted-network assumption.
04
Default deny is the backstop
Shared middleware refuses an unauthenticated request on any route that has not
explicitly opted out. A newly added route is closed until somebody deliberately
opens it, which is the opposite of the usual accident.
One honest caveat. The Docker Compose stack also publishes each service on a
direct host port for development smoke tests. Those ports bypass the gateway, and they
must not be exposed in production — the deployment guide says so, the production
preflight checks it, and we would rather you read it here than find it yourself.
Tenancy
Row-level security — and the condition under which it does nothing.
Every tenant-scoped table carries a PostgreSQL row-level security policy. That is
the easy half. The half most vendors leave out of the datasheet is that RLS does not
apply to the role that owns the table.
Isolation offthe failure mode
Connected as the database owner
The owner bypasses every policy. A tenant-scoped query returns every tenant's rows
and nothing anywhere warns you. This is documented PostgreSQL behaviour, not a
defect in the platform — which is precisely why it has to be designed against
rather than assumed away.
SELECT … FROM operations2 431 rows
tenants represented9
Isolation enforcedthe required configuration
Connected as the application role
A non-owner role, provisioned by make db-setup after the migrations
run. Policies apply on every read and every write. Cross-tenant reads and writes
are covered behaviourally, so the isolation is a tested property rather than a
diagram.
SELECT … FROM operations287 rows
tenants represented1
So the runtime refuses to start in the wrong one.
In production, if the application user is not set to the non-owner role, the
preflight fails and the stack does not come up. A misconfiguration becomes an
outage you notice at deploy time instead of a data leak you notice later.
scripts/production_preflight.py
POSTGRES_APP_USER must be the app role · fails closed when ENV is production
Why publish our own worst failure mode. Because a control you cannot inspect is a
promise, not a control. If this page only said "multi-tenant with row-level security",
you would have no way to tell whether the deployment in front of you actually enforces
it. Now you know exactly which line to check.
Integration
Services do not read each other's databases.
One database per service, each with its own Alembic history. Services integrate by
publishing onto an Apache Pulsar mesh under a shared EventEnvelope contract — never
by reaching into another service's tables. It costs a little latency and buys the
ability to change one service without a coordinated release of the other twenty-one.
One envelope
Every message carries event id, type, version, tenant and correlation id around its
payload. A consumer can reject what it does not understand instead of guessing at it.
Canonical topics
Topic names come from a shared module, never a string literal in a handler. A typo
becomes an import error at start-up rather than a subscription that is silently empty.
Failure is parked
Retries are bounded; what still fails lands on a dead-letter topic with the envelope
intact, so it can be replayed once the consumer is fixed. Nothing is dropped quietly.
Migrations stay local
A schema change in one service cannot break another service's reads, because no other
service reads it. That is the whole reason the databases are separate.
Deployment
Three modes. One codebase. The values file changes, not the platform.
An operator programme, a regulator and a national network run the same services with
different surfaces enabled. There is no separate build, no "enterprise fork", and
nothing you would have to migrate off if your remit grows.
Operator
Enterprise drone programmes
Plan → fly → prove, with SORA 2.5 and live conformance
Edge ingestion, video wall, fleet and crew management
Runs on your Kubernetes, or one Docker Compose host
PROFILE=operator
Authority
CAAs and ANSP innovation units
Approval workbench with jurisdiction rules and SLAs
ED-269 zone authoring and cross-operator supervision
Hash-linked audit trail with tenant-scoped export
PROFILE=authority
National
Country-scale programmes
DSS federation, Network Remote ID and CISP interfaces
Multi-authority delegation and cross-border workflows
Multi-region deployment with geo-replication values
PROFILE=national
Air-gapped is a first-class path, not a workaround.
The disconnected install is the same stack as the connected one. Images come from
your private registry, licences are signed and verified locally, and nothing calls
home to stay running — so a vendor outage cannot switch a control room off. What you
give up is listed plainly in the air-gapped playbook, because there is a real list.
Licence verificationSigned · offline · no phone-home
Map and terrain dataSeeded tiles, held locally
Local AI modelsWeights shipped in the bundle
UpdatesStaged bundles with rollback
Conformance
What is implemented, and how you check it yourself.
No independent conformance scheme for UTM platforms exists in most jurisdictions
today. Be wary of anyone who implies otherwise. What we publish instead is the scope
of each implementation, the maturity label it honestly carries, and the command that
regenerates its evidence on your own stack.
Standards ledger — dated runs, or an explicit cadence. Never a vague claim.
Standard
What is implemented
How it is evidenced
Status
ASTM F3548-21
Strategic deconfliction: operational-intent sharing, conflict detection and constraint awareness against a real DSS.
InterUSS qualifier suites pass with zero findings above Low severity.
make uss-qualifier · 2026-06-10
GA
ASTM F3411 v19 / v22a
Network Remote ID in both the Service Provider and Display Provider roles, on one deployment.
Verified by the same qualifier run against the reference DSS.
make uss-qualifier · 2026-06-10
GA
JARUS SORA 2.5
Full ground and air-risk methodology with the complete SAIL table. The go/no-go it produces is advisory — a human still approves.
Behaviourally pinned, not a lookup stub.
SAIL matrix suite · every CI run
GA
EUROCAE ED-269
Geographical-zone lifecycle: authoring, versioning, activation windows and publication, validated against the ED-269 model.
Schema contract tests; the official schema gate is a licensed capability.
ED-269 schema suite · every CI run
GA
EU 2021/664 U-space
Mandatory U-space service coverage across the platform capability set, including traffic information.
Capability contract tests. Field experience is still narrow — hence the label.
capability suite · every CI run
Beta
ASTM F3548-21ASTM F3411JARUS SORA 2.5EUROCAE ED-269EU U-spaceVerified, not certified.
Day two
The part that decides whether it survives a year.
Anyone can demonstrate a platform on a good day. These are the properties your
infrastructure team will ask about in the second meeting, and the reason they usually
say yes.
Observability, in the chart
Prometheus, Grafana, Loki, Jaeger and SLO alerts ship inside the Helm chart rather
than as a separate project you have to assemble. A correlation id issued at the
gateway follows the request through every service log and every span.
Scheduled backups are unremarkable; a restore nobody has rehearsed is a story you
tell an inquiry. Restore drills run in CI, and CloudNativePG with point-in-time
recovery is available on the high-availability path.
restore drill in CI · PITR on the HA path
Your identity provider, not ours
OIDC federation to the IdP you already run, with roles mapped by allowlist rather
than by whatever a token happens to assert. There is no vendor-hosted account
directory and no shadow set of users to deprovision separately.
OIDC SSO · allowlist role mapping
Licences that verify offline
Licences are signed and validated locally. The platform never calls a licence
server to keep running, which is what makes air-gapped operation ordinary rather
than exceptional — and what stops a vendor outage from becoming your outage.
signed offline licences · no phone-home
Give this page to your security reviewer.
The evaluation pack is the installer we ship to production, the architecture notes
behind everything above, and the conformance suites you can re-run without asking us
for permission.