TrustManager API is a tool to help enterprises and agencies organize, govern, and manage roots of trust for a PKI in a consistent manner. At its core, TrustManager API is a simple RESTful API built using Flask, which manages trust for digital certificates. The API allows users to add, retrieve, and manage certificates, including toggling their trust status. It further provides a feed of trusted certificates, enabling application/platform/server owners to get notified of trust changes. Lastly, TrustManager API includes batch jobs to build truststores in common formats/structures, to easily communicate trust to applications and operating systems.
flask-certificates-api
├── src
│ ├── app.py # Entry point of the application
│ ├── models
│ │ └── certificates.py # Defines the Certificate model
│ ├── routes
│ │ └── certificates.py # Contains route handlers for API endpoints
│ ├── db
│ │ └── database.py # Handles SQLite database connection and operations
│ ├── batch
│ │ ├── assemble_jks.py # Batch job: builds Java KeyStore from trusted certs
│ │ ├── assemble_pfx.py # Batch job: builds PKCS#12 (PFX) from trusted certs
│ │ ├── assemble_trusted_pem.py # Batch job: concatenates trusted certs as PEM
│ │ ├── assemble_rpm.py # Batch job: builds RPM package for trusted certs
│ │ └── assemble_group_policy.py # Batch job: builds GPO/Group Policy truststore
│ └── static
│ ├── index.html # Web-based admin GUI
│ ├── app.js # JavaScript for the admin GUI
│ ├── style.css # CSS for the admin GUI
│ ├── swagger.yaml # OpenAPI/Swagger specification
│ ├── trusted_certs.jks # Generated Java KeyStore (JKS)
│ ├── trusted_certs.pfx # Generated PKCS#12 (PFX)
│ ├── trusted_certs.pem # Concatenated PEM file
│ └── trusted-certs-1.0.0-1.noarch.rpm # Generated RPM package
├── requirements.txt # Lists project dependencies
├── Dockerfile # Docker container definition
├── license.txt # Project license
└── README.md # Documentation for the project
architecture-beta
service db(database)[Database]
service api(server)[API]
service batch(server)[Batch Jobs]
service gui(internet)[GUI]
service oidc(internet)[OIDC IdP]
db:R -- L:api
db:B -- L:batch
api:R -- L:gui
oidc:B -- T:api
TrustManager-API can require AuthN|Z for non-GET endpoints. By default, AuthN|Z is disabled, but can be enabled and configured at run-time. Authentication is handled by OpenID Connect, and authorization information is taken from the "Roles" assertion in the OIDC claim JWT (which needs to be a bearer-token). When AuthN|Z is enabled, all endpoints with write methods (PUT, POST) require the user to have the role "TrustAdmin". If you turn-on AuthN|Z, then you need to specify the Auth parms; if you are missing any of the Auth parms, it will run with Auth disabled.
All configuration for the application is taken from the environment as environment variables that start with "TRUSTMANAGER_".
The configurable parms available are:
- TRUSTMANAGER_DATABASE_URL: default "sqlite:///certificates.db"
- TRUSTMANAGER_REQUIRE_AUTH: default "False"
- TRUSTMANAGER_OIDC_CLIENT_ID: default ""
- TRUSTMANAGER_OIDC_CLIENT_SECRET: default ""
- TRUSTMANAGER_OIDC_METADATA_URL: default ""
Note: This is the recommended way to run this tool. It ensures the running environment has everything you need, and is configured correctly.
-
Set the configurable parms as exported environment variables:
All configuration for the application is taken from the environment as environment variables that start with "TRUSTMANAGER_"
export TRUSTMANAGER_DATABASE_URL='sqlite:///certificates.db' export TRUSTMANAGER_REQUIRE_AUTH=True export TRUSTMANAGER_OIDC_CLIENT_ID='TrustManager' export TRUSTMANAGER_OIDC_CLIENT_SECRET='asdfghjkl' export TRUSTMANAGER_OIDC_METADATA_URL='http://idp.example.gov/oidc/provider/default/.well-known/openid-configuration'
-
Build the container image, using the Dockerfile in the current folder:
docker build -t trustmanager-api . -
Run the container, passing-in the configurable parms exported above:
You can read more about passing environment variables from your host to your container at [https://docs.docker.com/reference/cli/docker/container/run/#env]
docker run \ -d \ -p 5100:5100 \ --env TRUSTMANAGER_DATABASE_URL \ --env RUSTMANAGER_REQUIRE_AUTH \ --env RUSTMANAGER_OIDC_CLIENT_ID \ --env TRUSTMANAGER_OIDC_CLIENT_SECRET \ --env TRUSTMANAGER_OIDC_METADATA_URL \ trustmanager-apiThe API will listen on port 5100
-
Clone the repository:
git clone <repository-url> cd flask-certificates-api
-
Create a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`-
Install dependencies:
pip install -r requirements.txt
-
Set the configurable parms as exported environment variables:
All configuration for the application is taken from the environment as environment variables that start with "TRUSTMANAGER_"
export TRUSTMANAGER_DATABASE_URL='sqlite:///certificates.db' export TRUSTMANAGER_REQUIRE_AUTH=True export TRUSTMANAGER_OIDC_CLIENT_ID='TrustManager' export TRUSTMANAGER_OIDC_CLIENT_SECRET='asdfghjkl' export TRUSTMANAGER_OIDC_METADATA_URL='http://idp.example.gov/oidc/provider/default/.well-known/openid-configuration'
-
Run the application:
python src/app.py
The API will listen on port 5100.
- Endpoint:
PUT /Certificate - Description: Accepts a PEM-encoded certificate, extracts necessary fields, computes the fingerprint, and stores the data in the database.
- Request Body: PEM-encoded certificate.
- Endpoint:
GET /Certificates - Description: Returns a JSON-encoded list of all certificates with their metadata.
- Endpoint:
POST /Trust - Description: Marks a certificate as trusted (only if self-signed) and updates the LastChanged time.
- Request Body: Certificate ID.
- Endpoint:
POST /Distrust - Description: Marks a certificate as not trusted and updates the LastChanged time.
- Request Body: Certificate ID.
- Endpoint:
GET /Certificates/atom - Description: Returns an ATOM XML feed of all certificates currently marked as trusted. The feed is updated automatically whenever a certificate is added or its trust status changes.
- Endpoint:
GET /Certificate/serial/{serial} - Description: Retrieve a certificate by its serial number.
- Response: PEM-encoded certificate.
- Endpoint:
GET /Certificate/subject/{subject} - Description: Retrieve certificate(s) by full or partial subject match.
- Response: List of PEM-encoded certificates.
- Endpoint:
GET /Certificate/fingerprint/{fingerprint} - Description: Retrieve a certificate by its fingerprint.
- Response: PEM-encoded certificate.
-
Endpoint:
POST /BatchJob -
Description: Initiate a batch job by name (such as building truststores).
-
Request Body:
{ "job": "<job_name>" } -
Available jobs:
assemble_jksassemble_pfxassemble_trusted_pemassemble_rpmassemble_group_policy
-
Response: JSON with job output or error.
-
Endpoint:
GET /BatchJob/list -
Description: Returns a list of available batch job names that can be executed via the API.
-
Response:
["assemble_jks", "assemble_pfx", "assemble_trusted_pem", "assemble_rpm", "assemble_group_policy"]
Batch jobs are provided in the src/batch directory to export trusted certificates in various formats:
-
assemble_jks.py:
Builds a Java KeyStore (JKS) containing all trusted certificates as root CAs. -
assemble_pfx.py:
Builds a PKCS#12 (PFX) bundle containing all trusted certificates as root CAs. -
assemble_trusted_pem.py:
Concatenates all trusted certificates into a single PEM file, with each certificate preceded by its subject and expiration date. -
assemble_rpm.py:
Builds an RPM package that installs all trusted certificates as separate files in/etc/pki/ca-trust/source/anchorson a target machine, and runsupdate-ca-trust enableandupdate-ca-trust extractto update the system trust store. Each certificate file is installed with ownerroot, grouproot, and permissions0644.
curl -X PUT -d "<PEM_CERTIFICATE>" http://localhost:5100/Certificatecurl -X GET http://localhost:5100/Certificatescurl -X POST -H "Content-Type: application/json" -d '{"id": 1}' http://localhost:5100/Trustcurl -X POST -H "Content-Type: application/json" -d '{"id": 1}' http://localhost:5100/Distrustcurl -X GET http://localhost:5100/Certificates/atomcurl -X POST -H "Content-Type: application/json" -d '{"job": "assemble_jks"}' http://localhost:5100/BatchJobcurl -X GET http://localhost:5100/Certificate/serial/123456789curl -X GET http://localhost:5100/Certificate/subject/Examplecurl -X GET http://localhost:5100/Certificate/fingerprint/abcdef123456curl -X GET http://localhost:5100/BatchJob/listA simple web GUI is available for administrators at http://localhost:5100/admin.
Features:
- Add new certificates
- View and search all certificates
- Trust/distrust certificates (with self-signed check)
- Download truststore files (JKS, PFX, PEM, RPM)
- View ATOM feed of trusted certificates
How to use:
- Start the Flask API.
- Open http://localhost:5100/admin in your browser.
- Use the interface to manage certificates and truststores.
Static files for the GUI are located in the static/ folder.
This project is licensed under the BSD License.
Swagger (interactive API documentation) licensed under the terms here


