Files
mgmt/README.md
scott 37a24d4bf5 add Postgres support with bundled and external (RDS) options
Helm chart:
- Add postgresql section to values with bundled and external modes
- Add postgres deployment, service, and PVC templates
- Construct DATABASE_URL dynamically with password from Secret
- Backend strategy switches to RollingUpdate when using Postgres
- SQLite PVC suppressed when Postgres is active

Backend:
- Add psycopg2-binary to requirements
- Make run.py schema migrations portable (BOOLEAN, TIMESTAMP, BYTEA types)
- Add Postgres-compatible name-split migration using SPLIT_PART/POSITION

Demo:
- Add docker-compose.postgres.yml for containerized Postgres
- Wire into demo.sh alongside Keycloak

Docs:
- Update CLAUDE.md, README, and design docs to reflect Postgres as primary DB
- Mark scalability SQLite blocker as resolved
- Update roadmap and keycloak-setup examples

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:51:21 -07:00

4.4 KiB

OSA Management Suite

Internal tool for managing projects, software licenses, and X.509 certificates.

Features

  • Projects — Track projects with key contacts (BFM, PM, Admin), search/sort, per-project detail pages
  • Licenses — Manage software license files with metadata (vendor, expiration, seat count), upload/download .lic files
  • Certificates — Store certs with encrypted private keys, import/export in PEM, DER, PKCS12, and PEM bundle formats
  • Dashboard — At-a-glance stats, expiring item alerts, audit activity feed

Quick Start

./dev.sh

Opens at http://localhost:5173. Default login: admin / admin.

Starts the Flask backend (:5001), Vite dev server (:5173), and Keycloak (:8180). First run installs dependencies automatically. Requires Python 3, Node.js, and Podman.

For a fully containerized setup with no local dependencies (only Podman + curl):

./demo.sh

Opens at http://localhost:8080.

Project Structure

├── backend/          Flask API (Python)
├── frontend/         React UI (TypeScript)
├── chart/osa-suite/  Helm chart for Kubernetes
├── dev.sh            Local development (with Keycloak)
├── demo.sh           Containerized development (no local deps)
└── build.sh          Build production containers

Configuration

Copy .env.example to backend/.env and fill in values:

cp .env.example backend/.env
Variable Required Description
SECRET_KEY Production Flask session signing key
FERNET_KEY Production Encryption key for cert private keys
AUTH_USERNAME No Login username (default: admin)
AUTH_PASSWORD_HASH Production Werkzeug password hash
DATABASE_URL No Database URI (default: sqlite:///osa.db, use postgresql:// for Postgres)
SESSION_COOKIE_SECURE No Set true behind TLS
FLASK_DEBUG No Enable debug mode (default: false)

Generate secrets:

# Secret key
python3 -c "import secrets; print(secrets.token_hex(32))"

# Fernet key
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

# Password hash
python3 -c "from werkzeug.security import generate_password_hash; print(generate_password_hash('yourpassword'))"

Building Containers

./build.sh

Push to a registry:

REGISTRY=registry.example.com/team TAG=v1.0.0 ./build.sh

Kubernetes Deployment

Requires Helm 3.

helm install osa ./chart/osa-suite \
  --set secrets.fernetKey="<your-fernet-key>" \
  --set secrets.secretKey="<your-secret-key>" \
  --set auth.passwordHash="<your-hash>"

The chart creates:

  • Backend Deployment + Service (Flask/gunicorn on port 5001)
  • Frontend Deployment + Service (nginx on port 80)
  • Postgres Deployment + Service + PVC (when postgresql.enabled=true)
  • Secret with app credentials, encryption keys, and database password
  • Optional Ingress (set ingress.enabled=true)

Helm Values

Value Default Description
imageRegistry "" Container registry prefix
backend.replicas 1 Backend replicas (scale freely with Postgres)
frontend.replicas 1 Frontend replicas (scale freely)
postgresql.enabled false Deploy bundled Postgres container
postgresql.password "" Postgres password (required when enabled)
postgresql.external.host "" External Postgres host (e.g., RDS endpoint)
postgresql.external.sslMode "" SSL mode for external Postgres (require, verify-full)
ingress.enabled false Create Ingress resource
ingress.host osa.example.com Ingress hostname
ingress.tls false Enable TLS

See chart/osa-suite/values.yaml for all options.

Tech Stack

Layer Technology
Backend Python, Flask, SQLAlchemy, gunicorn
Frontend React, TypeScript, Tailwind CSS, shadcn/ui
Database PostgreSQL (SQLite fallback for dev)
Encryption Fernet (AES-128-CBC + HMAC-SHA256)
Containers Docker, nginx
Orchestration Kubernetes, Helm

Roadmap

  • Keycloak SSO integration (OAuth/OIDC)
  • PostgreSQL migration
  • AWS Secrets Manager for private key storage
  • Row-level project access control
  • License expiration email alerts