Serving an API over mTLS
Tutorial 3 — Running an mTLS API server
Scenario: Alice wants to expose her own API at ORNL so that trusted collaborators (like Bob) can call it.
1. Write a FastAPI application
# ornl_api/server.py
from fastapi import FastAPI
from certified.fast import ClientName
app = FastAPI()
@app.get("/hello")
async def hello(name: ClientName):
return {"message": f"Hello, {name}!"}
ClientName is a FastAPI dependency that extracts the caller's common name
from the mTLS peer certificate — no manual cert parsing needed.
See the FastAPI integration reference for more dependencies.
2. Add Alice's service identity
If Alice's personal identity is already set up (Tutorial 1), she can create a separate service identity for her API server:
certified init \
--org 'Oak Ridge National Laboratory' --unit 'Materials Science' \
--domain materials.ornl.gov \
--host materials.ornl.gov --host localhost \
--email ops@ornl.gov \
--config $VIRTUAL_ENV/etc/certified
3. Trust Bob's certificate
For Bob to call Alice's API, his CA must appear in known_clients/:
# Bob exports his CA cert: certified get-signer > bob_ca.json
# Alice installs it:
certified add-client bob-nist bob_ca.json \
--config $VIRTUAL_ENV/etc/certified
See Trust a client for details.
4. Start the server
certified serve \
--config $VIRTUAL_ENV/etc/certified \
ornl_api.server:app \
https://0.0.0.0:8443
Bob can now call Alice's API using the cross-org identity he issued her in
Tutorial 2, and the ClientName dependency will greet him by name.
For structured JSON logging, see Rich JSON logging.