consentml

open source · MIT · pip install consentml

When a user asks to be forgotten, which models trained on them?

Add one decorator to your training function. ConsentML records what each model actually learned from, and when consent is revoked it names the affected models and proves the record was never edited.

$ pip install consentml
Star on GitHub

Works with in-memory dataframes, Postgres, and Snowflake. Python 3.10+.

the full flow — recorded live, not mocked
Terminal demo: train two models with @track, run consentml verify to confirm the audit chain is intact, run consentml revoke to list the two models affected by a subject's consent revocation, then export the dossier.
record lineage → verify the chain → name the affected models → export the dossier

how it works

Three commands stand between a revocation request and a filed answer.

The lineage is a hash-chained ledger: each run links to the last, so the record can be checked, not just trusted.

01

Record lineage at load time

ConsentML loads the training data itself, so what it records cannot disagree with what the model actually trained on. Credentials are never stored; subjects are kept as one-way hashes.

@track(model_name="churn-risk", source=PostgresSource(...))
def train(df): ...
02

Verify the record is untampered

Verification checks the chain and that it still agrees with the live tables — catching a row deleted to hide that someone was in a training set, which the chain alone cannot see.

$ consentml verify --db lineage.db
Audit log OK: 2 entries, chain intact.
03

Answer the revocation in one command

Name the deployed models that learned from a subject's data, with a recommendation for each — then export the dossier you actually file.

$ consentml revoke --subject-id alice@example.com
2 affected models for subject ff8d9819fc0e…
  - churn-risk   recommendation=retrain
  - ltv-forecast recommendation=retrain
Aug 2, 2026the clock already started

The EU AI Act's Article 50 transparency obligations took effect this year, with higher-risk duties staged in behind them. Regulators are starting to ask providers to show their work on training data. "We deleted the row, trust us" will not survive that question — an auditor's next one is immediate: prove the record was not edited after the fact.

one decorator

It reads like the training code you already write.

The source is fixed when the decorator runs, so a tracked function cannot later be called against different data than the lineage records.

from consentml import track
from consentml.sources.postgres import PostgresSource

@track(
    model_name="readmission-risk",
    source=PostgresSource(
        dsn="postgresql://user:pw@db.internal/clinic",
        query="SELECT patient_id, age, ldl, outcome FROM patients",
        subject_id_col="patient_id",
    ),
)
def train(df):
    return LogisticRegression().fit(df[["age", "ldl"]], df["outcome"])

model = train()   # no argument: ConsentML supplies the data it recorded

an honest boundary

ConsentML reports. It does not decide for you.

Deciding what to do about an affected model is a judgment call that depends on the model, the risk, and the law. A tool that silently picked one answer would be dangerous.

What it does

  • Records which subjects reached which training runs
  • Keeps a tamper-evident, hash-chained audit trail
  • Names the models affected by a revocation
  • Exports a per-subject dossier (HTML, JSON, or PDF)

What it does not do

  • Delete data from your systems
  • Modify, retrain, or unlearn a model for you
  • Decide whether an affected model is a problem
  • Give legal advice on your obligations

ready in one line

Make the erasure question one you can answer.

$ pip install consentml
Read the quickstart