Skip to content

Control-Plane Certification

Cloud-Native Telecom Certification (CNTC) is an open, reproducible framework that turns 3GPP specifications into an automated pass / fail certificate for a 5G core. This release adds the control-plane engine, cpbench, which certifies the core's network functions: AMF, SMF, NRF, AUSF and UDM.

The model in one line: a published standard, then automated tests, then a pass/fail gate, then a per-NF certificate. Every run is executed against your live core, and every result is a real observation on the wire or over the Service-Based Interface.

CNTC control-plane architecture: the cpbench engine drives each network function over its real interfaces, N1 and N2 through a simulated gNB and UE and the Service-Based Interface for the HTTP/2 network functions, while observers capture NAS on N2 and PFCP on N4; results flow into the cntc umbrella, which grades them against a per-NF requirement catalog and issues certificates.

The cpbench engine measures, and the cntc umbrella judges. Keeping those two layers decoupled is what lets one grading core certify both the user plane and the control plane.

Most of the industry can certify a device or a base station, but there is no open, reproducible way to certify a 5G core network function against its own 3GPP spec. Commercial tools that do this (Spirent, Keysight, Valid8, Emblasoft) are closed and expensive.

CNTC fills that gap with two decoupled layers:

LayerRoleShips in this release
cpbench engineMeasures. Drives each NF over its real interfaces and records resultscontrol plane (AMF / SMF / NRF / AUSF / UDM)
cntc umbrellaJudges. Grades results against a per-NF requirement catalog and issues a certificatereused, unchanged

The umbrella is pure and data-driven: it grades whatever test IDs appear in a results.json against a YAML catalog. The same umbrella already certifies the user plane (the UPF, via the sibling upfbench engine), so one grading core certifies the whole core.

How it tests, per NF and standard-anchored

Section titled “How it tests, per NF and standard-anchored”

Every test maps to a clause of that NF's own 3GPP specification, covering both its stage-3 protocol spec and its SCAS security-assurance spec:

NFProtocolSCASDriven via
AMFTS 24.501 (NAS) · TS 38.413 (NGAP) · TS 33.501 (5G-AKA)TS 33.512UERANSIM over N1/N2 plus on-the-wire capture
SMFTS 29.502 (Nsmf) · TS 29.244 (N4/PFCP)TS 33.515PDU sessions via UERANSIM plus N4 capture
NRFTS 29.510 (Nnrf)TS 33.518SBI client (HTTP/2 + TLS + OAuth2)
AUSFTS 29.509 (Nausf)TS 33.516SBI client plus transitive via registration
UDMTS 29.503 (Nudm)TS 33.514SBI client plus transitive via registration

It drives each NF with a spec-compliant UE and SBI client, then observes the result. That includes capturing NAS on N2 and PFCP on N4 and decoding them, so security properties (NAS ciphering, control to dataplane binding, no auth bypass) are proven on the wire rather than assumed.

LevelProvesTestsStatus
Level 1: Conformance & Observable Securityeverything provable with a spec-compliant peer plus observation44 (26 essential)shipped, v1.0
Level 2: Adversarial Robustness & Privileged Interopeverything needing a non-compliant or privileged peer (forged, replayed or malformed state; registered-NF PKI)20roadmap

The Level-1 guarantee: every L1 test is implemented, so a verdict is never INCOMPLETE because the tester did not build something. When a case genuinely cannot be judged on a deployment (the core enforces no OAuth2, or there is no UE to drive registration) the result is a transparent INCOMPLETE about that deployment: a reported gap, never a silent pass. An NF earns its certificate only when all its essential tests pass.

Verified against a live free5GC on both deployment styles. Same tests, same NFs, different result, because the difference is the deployment's hardening (and what the rig can exercise), not the tests:

NFDocker free5GCKubernetes free5GC (Helm + in-cluster UE)
AMFPASS (9/9)PASS (9/9)
AUSFPASSINCOMPLETE1
UDMPASSINCOMPLETE1
SMFFAIL, no TLS on SBIFAIL2
NRFFAIL, no TLS on SBIFAIL, serves discovery to an unauthenticated client (HTTP 200) and no TLS

Docker: 3 of 5 certifiable. Kubernetes: AMF certifies, covering the full attach cycle (registration, 5G-AKA, NAS ciphering and integrity, and a wrong-key negative attach) driven by an in-cluster UE. Same harness, and it still surfaces every gap: the Kubernetes NRF serves the network topology to an unauthenticated client, a real authorization finding that the OAuth2-enforcing docker core does not have. The framework reports the gap. It does not rubber-stamp, and never fakes a pass.

1 AUSF and UDM core auth and subscription pass transitively, via registration; their SBI-authorization case is na because the default Helm free5GC does not enforce OAuth2, so a token-less call returns 400 rather than 401 or 403 and there is no authorization decision to grade.
2 the in-cluster single-node UPF has no N6 route, so the PDU-session data-path case cannot complete.

Five steps, from a clean machine to a signed certificate. Each step below is self-contained: run them in order.

Clone the repository from the main branch. The bootstrap script installs the system and Python dependencies and builds UERANSIM from source.

# clone the repository (main branch)
git clone -b main https://github.com/TOSSI-Foundation/CNTC.git
cd CNTC

# installs system deps, Python deps, and builds UERANSIM from source
./scripts/bootstrap_cpbench.sh

Step 2: Deploy the 5G core you want to certify

Section titled “Step 2: Deploy the 5G core you want to certify”

CNTC is bring-your-own-core. Deploy the core under test however you normally would, on docker or on Kubernetes. It is tested against free5GC, Open5GS and OAI. Nothing needs to be installed into the core itself: CNTC drives it over its real interfaces, exactly as a peer network function would.

The wizard auto-detects whether the core runs on docker or Kubernetes and writes a config for it. Then run the doctor: it must print READY before you continue.

# build a config (auto-detects docker vs Kubernetes)
make cp-configure

# preflight the rig; must print READY
make cp-doctor CONFIG=configs/<your>.yaml

Addresses are resolved live on every run (docker inspect or kubectl get svc), so redeploying the core needs zero config edits. The config holds only what cannot be derived (the N2 endpoint, the capture interface, subscriber credentials), and the wizard auto-detects even those.

Step 4: Run, grade, and issue certificates

Section titled “Step 4: Run, grade, and issue certificates”

cp-run drives every network function and writes a results.json. cntc verdict grades those results against the profile's requirement catalog, and cntc certify issues a certificate when every essential test passes.

# drive all NFs and record results
make cp-run    CONFIG=configs/<your>.yaml NF=all

# grade the results, then issue the certificate
cntc verdict   campaigns/<id>/results.json --profile amf-conformance
cntc certify   campaigns/<id>/results.json --profile amf-conformance

Swap --profile for the NF you are certifying, and use NF=amf (or smf, nrf, ausf, udm) to run a single one instead of all.

The dashboard is a live web view over every campaign you have run, with per-NF scorecards and the issued certificates.

make dashboard

The repository holds both certification engines plus the shared grading core:

DirectoryWhat it holds
cpbench/the control-plane engine (adapters, drivers, observers, suites)
cntc/the grading umbrella (verdict engine, certificate issuer, standards catalogs)
cntc_common/the shared results schema
upfbench/the sibling user-plane (UPF) engine
dashboard/the live web dashboard over all campaigns
scripts/bootstrap, config wizard, run helpers
docs/architecture, the levels guide, the implementation report, diagrams
  • UERANSIM, the gNB and UE simulator (N1/N2). AGPL-3.0; fetched and built by the bootstrap rather than bundled, so CNTC invokes it as a separate process and the two licenses never mix.
  • SBI client, our own HTTP/2 + TLS + OAuth2 client for Nnrf, Nausf, Nudm, Namf and Nsmf.
  • tcpdump and tshark, to capture and decode N2 (NAS) and N4 (PFCP) on the wire.
  • pfcpsim, for N4/PFCP driving and observation.

Apache-2.0. External drivers keep their own licenses and are fetched separately (UERANSIM is AGPL-3.0). See NOTICE or the bootstrap script for details.