AI News HubLIVE
In-site rewrite5 min read

AI_glue – drop-in audit and governance for OpenAI and Anthropic apps

AI_glue is an open-source transparent proxy that adds logging, spend tracking, PII detection, and governance to AI apps with zero code changes. It supports proxy and wrapper modes, multi-instance aggregation, and provides a unified dashboard with executive and audit views.

SourceHacker News AIAuthor: vigcneiugh

Notifications You must be signed in to change notification settings

Fork 0

Star 0

BranchesTags

Open more actions menu

Folders and files

NameName

Last commit message

Last commit date

Latest commit

History

13 Commits

13 Commits

docs

docs

examples

examples

routes

routes

src

src

static

static

templates

templates

tests

tests

.env.example

.env.example

.gitignore

.gitignore

CLAUDE.public.md

CLAUDE.public.md

CONTRIBUTING.md

CONTRIBUTING.md

LICENSE

LICENSE

README.md

README.md

app.py

app.py

governance.yaml.example

governance.yaml.example

requirements.txt

requirements.txt

Repository files navigation

Drop-in AI observability and governance for OpenAI and Anthropic applications.

What ai_glue gives you

Every AI call logged — provider, model, tokens, cost, latency, project, session

Spend visibility by project, team, and environment

PII detection with per-call flag review workflow

Hard governance rules — block unapproved models, enforce cost caps and rate limits

Multi-instance aggregation — dev, staging, and prod in one unified dashboard

Role-split views: engineering audit log, executive spend summary, per-instance breakdown

Add governance to existing apps with one environment variable change — no code rewrites

What ai_glue is not

ai_glue does not replace your AI stack. It has no opinion on prompts, agents, RAG pipelines, or orchestration. It sits between your applications and model providers to add governance, auditing, spend visibility, and policy enforcement. Think of it as a transparent proxy with a dashboard — not a framework.

Deployment models

Evaluating / self-hosted — you are both the operator and the user. Clone it, add your own API key to .env, run it on your machine. The quickstart below covers this case.

Team deployment — IT deploys one ai_glue instance on a shared server with the organization's API key in .env. Individual developers never touch an API key. They change one environment variable on their machine and everything is logged, governed, and visible on the shared dashboard.

┌─────────────────────────────────────┐ dev laptop │ ai_glue server │ ANTHROPIC_BASE_URL ───►│ .env: ANTHROPIC_API_KEY=sk-org-... │──► Anthropic API │ dashboard: http://ai-glue.internal │ └─────────────────────────────────────┘

Quickstart (local / evaluation)

git clone https://github.com/simonhansedasi/ai_glue.git cd ai_glue pip install -r requirements.txt cp .env.example .env # add your API keys cp governance.yaml.example governance.yaml python examples/governance_demo.py # no API keys needed python app.py # http://localhost:5010

Two integration modes

Mode 1 — Proxy (zero code changes)

Point existing apps at ai_glue instead of the real provider. One environment variable per app:

Anthropic

ANTHROPIC_BASE_URL=http://your-host:5010/proxy/anthropic

OpenAI

OPENAI_BASE_URL=http://your-host:5010/proxy/openai/v1

Every call is intercepted, logged, and governance-checked. The app receives the real response unchanged. Streaming is fully supported — the proxy passes the stream through and captures token counts and latency at the end.

Tag calls with optional headers for project and session labeling:

X-Aiglue-Project: hr-bot X-Aiglue-Session: user-123

If no headers are present, calls fall back to AIGLUE_DEFAULT_PROJECT / AIGLUE_DEFAULT_SESSION from .env.

Mode 2 — Wrapper (new apps or when you control the code)

from src import GluedClient

Anthropic — same API as anthropic.Anthropic()

client = GluedClient("anthropic", session_id="user-123", project="hr-bot") response = client.messages.create( model="claude-sonnet-4-6", max_tokens=512, messages=[{"role": "user", "content": "..."}], )

OpenAI — same API as openai.OpenAI()

client = GluedClient("openai", session_id="user-123", project="support-bot") response = client.chat.completions.create( model="gpt-4o", max_tokens=512, messages=[{"role": "user", "content": "..."}], )

Governance

Edit governance.yaml to configure rules. Changes apply immediately — no restart needed.

model_allowlist: # hard-block calls to unapproved models (403)

  • claude-sonnet-4-6
  • gpt-4o

pii_detection: true # flag prompts containing emails, SSNs, phones, credit cards

pii_allowlist: # exact strings that should never trigger a PII flag

projects: hr-bot: daily_cost_cap_usd: 5.00 # hard-block once daily spend hits cap rate_limit_per_hour: 100 # hard-block sessions that exceed call frequency

PII detection is regex-based (not ML). Hard-blocking violations are never logged — the call was never made. PII flags are logged as warnings and do not block calls.

Security note: governance.yaml becomes a sensitive file if you use the team API key mapping feature (see below), since it maps key prefixes to real project names. Treat it like .env in production — restrict filesystem permissions and do not commit it. governance.yaml is gitignored by default for this reason.

Dashboard

All three views draw from the same unified dataset merged across all instances.

/ — Audit (engineers / team leads)

Full call log. Every call from every instance in one table. Summary cards, daily charts, and by-project/by-model breakdowns are all merged across instances. Per-session drilldown shows individual turns, tool calls, and highlights flagged PII inline. Filters: ?project=X, ?session=X, ?flagged=1.

/executive — Executive view (leadership)

Non-technical. No session IDs, no model names. Cards: Total AI Spend, Projects Active, Conversations, Risk Flags. Charts: Spend by Project, Daily Spend trend. Unreviewed PII flags and governance blocks surface as a risk callout with a "Mark all reviewed" action.

/aggregate — Per-instance breakdown

One panel per instance with its individual summary, by-project table, and by-model table. Useful for comparing dev vs. staging vs. prod activity side by side.

Multi-instance aggregation

Run one ai_glue instance per environment. A parent instance pulls /api/summary from each child and merges everything into a single unified view.

Dev instance ──┐ Staging instance ─┼──► Parent instance ──► unified /, /executive, /aggregate Prod instance ──┘

To add a child — edit governance.yaml on the parent only, no code changes:

aggregator: children:

  • name: prod

url: http://prod-host:5010

  • name: staging

url: http://staging-host:5010

Set AIGLUE_INSTANCE_NAME on each child so it appears with a meaningful label in parent views.

Per-team API key mapping

Issue each team a synthetic key with a recognizable prefix. Teams swap their real provider key for it — no other changes needed. The proxy detects the prefix, tags all calls with the team's project name, and substitutes the real API key before forwarding. This enables centralized billing, per-team spend attribution, and chargeback models without distributing raw provider keys.

teams: sk-aiglue-eng: name: engineering sk-aiglue-marketing: name: marketing

Add spend caps or rate limits per team by adding the team name to projects: in governance.yaml.

What gets logged

Field Description

ts UTC timestamp

provider anthropic / openai

model exact model string

session_id caller-supplied, auto-detected, or default

project caller-supplied, auto-detected, or default

input_tokens from API response

output_tokens from API response

cost_usd estimated from token counts

latency_ms wall time

prompt_hash MD5 of prompt

raw_prompt full text (if AIGLUE_LOG_RAW=true)

raw_response full text (if AIGLUE_LOG_RAW=true)

gov_flags JSON array of warning strings

error exception message if call failed

reviewed_at timestamp when flags were acknowledged

Set AIGLUE_LOG_RAW=false in .env to store only the hash when prompt content is sensitive. Restrict filesystem permissions on audit.db in production — it contains call metadata and optionally raw prompts.

Training data export

ai_glue logs every prompt and response, which means your audit database doubles as a conversation dataset. The /export/training endpoint turns logged conversations into JSONL you can use for fine-tuning, content mining, or building provider-independent capability baselines.

This is particularly useful when a model you depend on is deprecated or sunsetted — if your conversations were logged through ai_glue, you have the raw material to fine-tune a replacement rather than starting from scratch.

Export a single conversation

On any session page (/session/), click Export JSONL to download that conversation as a single-session JSONL record.

Via URL directly:

/export/training?format=session&session=

Export all conversations for a project

On any project page (/project/), click Export all conversations to download every session for that project.

Via URL:

/export/training?format=session&project=

Output formats

format=session — one JSONL line per full conversation, with alternating user/assistant turns. Compatible with most fine-tuning pipelines.

{ "session_id": "conv-a3f9b2", "project": "support-bot", "model": "claude-sonnet-4-6", "messages": [ {"role": "user", "content": "How do I reset my password?"}, {"role": "assistant", "content": "You can reset your password by..."}, {"role": "user", "content": "I don't see that option."}, {"role": "assistant", "content": "Try navigating to..."} ] }

format=turn (default) — one JSONL line per API call, as isolated prompt/completion pairs. Useful for token-level analysis or simpler fine-tuning setups.

{"prompt": "How do I reset my password?", "completion": "You can reset your password by...", "model": "claude-sonnet-4-6", "session_id": "conv-a3f9b2", "project": "support-bot", "ts": "2026-05-15 10:00:00"}

Filters

All filters can be combined:

Param Example Effect

project ?project=hr-bot Only conversations from this project

session ?session=conv-abc Only this session

model ?model=gpt-4o Only calls made to this model

since ?since=2026-01-01 Only calls on or after this date

exclude_flagged ?exclude_flagged=true Drop calls with PII or governance flags

Notes

Calls are only exportable if AIGLUE_LOG_RAW=true (the default). Rows logged with AIGLUE_LOG_RAW=false are excluded from training exports.

The export queries the local instance's database only. Cross-instance export requires fetching from each child directly.

The user message for each turn is extracted from the end of the stored prompt string — the format is stable for standard single-user, single-assistant conversations.

Tests

pytest tests/ -v

27 tests. No API keys required. All LLM calls are mocked.

Stack

Python 3.7+, Flask, SQLite

Chart.js (CDN, no build step)

Anthropic SDK, OpenAI SDK

Environment variables

Variable Default Description

ANTHROPIC_API_KEY — API key used by the server to forward calls. In team deployments, only the server's .env needs this — individual developers do not.

OPENAI_API_KEY — Same as above for OpenAI.

AIGLUE_DB audit.db Path to SQLite audit database

AIGLUE_LOG_RAW true Store full prompt/response text

AIGLUE_DEFAULT_PROJECT proxy Project label for untagged proxy calls

AIGLUE_DEFAULT_SESSION proxy Session label for untagged proxy calls

AIGLUE_INSTANCE_NAME (AIGLUE_DEFAULT_PROJECT) Label shown in parent aggregator views

License

MIT

About

No description, website, or topics provided.

Resources

Readme

License

MIT license

Contributing

Contributing

Uh oh!

There was an error while loading. Please reload this page.

Activity

Stars

0 stars

Watchers

0 watching

Forks

0 forks

Report repository

Releases

4 tags

Packages 0

Uh oh!

There was an error while loading. Please reload this page.

Contributors

Uh oh!

There was an error while loading. Please reload this page.

Languages

Python 70.2%

HTML 24.9%

CSS 4.9%