Certificore - Certificate Lifecycle Platform

Overview

Enterprise-grade certificate lifecycle management platform. Unified API for managing certificates across multiple Certificate Authorities (Vault PKI, ADCS, ACME/Let’s Encrypt, DigiCert).

Inspiration: Swagger/OpenAPI learning project with real-world enterprise applicability.

Problem Statement

Certificate management pain points:

  • Certificates scattered across multiple CAs

  • No unified inventory or expiry tracking

  • Manual renewal processes prone to outages

  • Compliance reporting requires manual aggregation

  • No visibility into where certificates are deployed

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Certificore API                        │
│                    (FastAPI + OpenAPI)                      │
├─────────────────────────────────────────────────────────────┤
│  /authorities  /certificates  /policies  /deployments      │
└───────────────────────┬─────────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
        ▼               ▼               ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│  Vault PKI   │ │    ADCS      │ │ Let's Encrypt│
│  (DOMUS)     │ │  (Legacy)    │ │   (ACME)     │
└──────────────┘ └──────────────┘ └──────────────┘
        │               │               │
        └───────────────┴───────────────┘
                        │
                        ▼
              ┌──────────────────┐
              │   PostgreSQL     │
              │  (Source of      │
              │   Truth)         │
              └──────────────────┘

Database Schema

-- Certificate Authorities
CREATE TABLE ca_authorities (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    type VARCHAR(50) NOT NULL, -- vault, adcs, acme, digicert
    endpoint VARCHAR(512),
    config JSONB,
    enabled BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Certificates
CREATE TABLE certificates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    ca_id UUID REFERENCES ca_authorities(id),
    common_name VARCHAR(255) NOT NULL,
    sans TEXT[], -- Subject Alternative Names
    serial_number VARCHAR(255),
    fingerprint_sha256 VARCHAR(64),
    not_before TIMESTAMPTZ,
    not_after TIMESTAMPTZ,
    key_type VARCHAR(20), -- rsa, ecdsa, ed25519
    key_size INTEGER,
    status VARCHAR(20) DEFAULT 'active', -- active, revoked, expired
    pem_certificate TEXT,
    metadata JSONB,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Policies
CREATE TABLE policies (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL UNIQUE,
    description TEXT,
    min_key_size INTEGER DEFAULT 2048,
    max_ttl_days INTEGER DEFAULT 365,
    allowed_key_types TEXT[] DEFAULT ARRAY['rsa', 'ecdsa'],
    allowed_domains TEXT[],
    require_san BOOLEAN DEFAULT true,
    auto_renew_days INTEGER DEFAULT 30,
    enabled BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Deployments (where certs are installed)
CREATE TABLE deployments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    certificate_id UUID REFERENCES certificates(id),
    target_type VARCHAR(50), -- server, loadbalancer, ise, keycloak
    target_host VARCHAR(255),
    target_path VARCHAR(512),
    deployment_method VARCHAR(50), -- manual, ssh, api, kubernetes
    last_deployed TIMESTAMPTZ,
    status VARCHAR(20) DEFAULT 'pending',
    metadata JSONB,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Audit Log
CREATE TABLE audit_log (
    id BIGSERIAL PRIMARY KEY,
    action VARCHAR(50) NOT NULL,
    entity_type VARCHAR(50),
    entity_id UUID,
    actor VARCHAR(255),
    details JSONB,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Indexes
CREATE INDEX idx_certificates_expiry ON certificates(not_after);
CREATE INDEX idx_certificates_cn ON certificates(common_name);
CREATE INDEX idx_deployments_cert ON deployments(certificate_id);
CREATE INDEX idx_audit_entity ON audit_log(entity_type, entity_id);

API Endpoints (OpenAPI)

Authorities

Method Endpoint Description

GET

/authorities

List all certificate authorities

POST

/authorities

Register new CA

GET

/authorities/{id}

Get CA details

POST

/authorities/{id}/sync

Sync certificates from CA

Certificates

Method Endpoint Description

GET

/certificates

List all certificates (paginated)

POST

/certificates/issue

Issue new certificate

GET

/certificates/{id}

Get certificate details

POST

/certificates/{id}/renew

Renew certificate

DELETE

/certificates/{id}

Revoke certificate

GET

/certificates/expiring

List expiring certs (?days=30)

GET

/certificates/search

Search by CN, SAN, fingerprint

Policies

Method Endpoint Description

GET

/policies

List all policies

POST

/policies

Create policy

GET

/policies/{id}/evaluate

Evaluate cert against policy

Deployments

Method Endpoint Description

GET

/deployments

List all deployments

POST

/deployments

Register deployment target

POST

/deployments/{id}/deploy

Deploy certificate to target

GET

/deployments/{id}/status

Check deployment status

Compliance & Reporting

Method Endpoint Description

GET

/compliance/report

Full compliance report

GET

/compliance/expiring

Expiring certificates report

GET

/compliance/policy-violations

Policy violation report

POST

/webhooks

Register webhook for alerts

Tech Stack

Component Technology

Language

Python 3.11+

Framework

FastAPI (auto OpenAPI generation)

Database

PostgreSQL 15+

ORM

SQLAlchemy 2.0 + Alembic (migrations)

Validation

Pydantic v2

Auth

OAuth2 / API Keys

Async

asyncio + asyncpg

Testing

pytest + httpx

Docs

Swagger UI + ReDoc (built into FastAPI)

MVP Milestones

Phase 1: Foundation (2 weeks)

  • PostgreSQL schema + migrations

  • FastAPI project structure

  • CRUD for authorities, certificates, policies

  • OpenAPI spec auto-generation

  • Basic auth (API keys)

Phase 2: Vault Integration (1 week)

  • Vault PKI provider adapter

  • Issue certificates via API

  • Sync existing certs from Vault

  • Certificate renewal workflow

Phase 3: Monitoring & Alerts (1 week)

  • Expiry tracking job

  • Webhook notifications

  • Compliance evaluation

  • Basic dashboard endpoint

Phase 4: Deployment Automation (2 weeks)

  • Deployment target registry

  • SSH-based deployment

  • API-based deployment (ISE, Keycloak)

  • Deployment status tracking

Scale Considerations

Multi-tenancy

-- Add tenant_id to all tables
ALTER TABLE certificates ADD COLUMN tenant_id UUID;
CREATE INDEX idx_certificates_tenant ON certificates(tenant_id);

Event Streaming

  • Kafka/NATS for async operations

  • Certificate issued/renewed/revoked events

  • Integration with SIEM

High Availability

  • PostgreSQL replication

  • Stateless API (horizontally scalable)

  • Redis for caching + rate limiting

Integration Points

System Integration

HashiCorp Vault

PKI secrets engine API

Microsoft ADCS

DCOM/WMI or certreq CLI

Let’s Encrypt

ACME protocol (certbot library)

Kubernetes

cert-manager CRDs

ISE

ERS API for cert deployment

Keycloak

Admin API for cert updates

ServiceNow

Incident creation for expiring certs

Slack/Teams

Webhook notifications

Repository Structure

certificore/
├── alembic/                 # Database migrations
│   └── versions/
├── app/
│   ├── api/
│   │   ├── v1/
│   │   │   ├── authorities.py
│   │   │   ├── certificates.py
│   │   │   ├── policies.py
│   │   │   └── deployments.py
│   │   └── deps.py          # Dependencies (auth, db)
│   ├── core/
│   │   ├── config.py
│   │   └── security.py
│   ├── db/
│   │   ├── models.py
│   │   └── session.py
│   ├── providers/           # CA adapters
│   │   ├── base.py
│   │   ├── vault.py
│   │   ├── adcs.py
│   │   └── acme.py
│   ├── schemas/             # Pydantic models
│   │   ├── authority.py
│   │   ├── certificate.py
│   │   └── policy.py
│   └── main.py
├── tests/
├── docker-compose.yml
├── Dockerfile
├── pyproject.toml
└── README.md