Identity-Per-Transaction for regulated data pipelines.
Like a mayfly, these credentials live for exactly one transaction.
Most enterprise "zero trust" implementations authenticate once and trust indefinitely. A single compromised credential — a leaked IAM role, a stolen service account key, a reused session token — exposes your entire data lake for hours or days.
Identity-Per-Transaction (IPT) issues credentials scoped to exactly one resource for exactly one transaction. A compromised credential exposes one object. When that object is deleted post-processing, the credential points at nothing for the remainder of its TTL.
Traditional model: compromised key → entire data lake
IPT model: compromised key → single S3 object key (now deleted)
pip install pymayfly[aws] # AWS STS backend (FedRAMP-suitable)
pip install pymayfly[azure] # Azure Blob backend (AAD User Delegation SAS)
pip install pymayfly[gcp] # GCS backend (impersonation + downscoped tokens)
pip install pymayfly # core only — bring your own providerimport boto3
from pymayfly import IPTEnforcer, AWSSTSBroker, FileAuditLedger
enforcer = IPTEnforcer(
broker=AWSSTSBroker(role_arn="arn:aws:iam::123456789012:role/IPTProcessor"),
ledger=FileAuditLedger("/var/log/mayfly/audit.jsonl"),
)
@enforcer.protect(
resource_from=lambda e: (
f"arn:aws:s3:::{e['Records'][0]['s3']['bucket']['name']}"
f"/{e['Records'][0]['s3']['object']['key']}"
),
action="read",
)
def handler(event, context, *, creds):
s3 = boto3.client(
"s3",
aws_access_key_id=creds.token["AccessKeyId"],
aws_secret_access_key=creds.token["SecretAccessKey"],
aws_session_token=creds.token["SessionToken"],
)
record = event["Records"][0]
bucket = record["s3"]["bucket"]["name"]
key = record["s3"]["object"]["key"]
data = s3.get_object(Bucket=bucket, Key=key)
# process, de-identify, write to clean zone
# delete source object → credential now points at nothingfrom pymayfly import transaction_scope, AWSSTSBroker
broker = AWSSTSBroker(role_arn="arn:aws:iam::123456789012:role/IPTProcessor")
with transaction_scope(
broker,
resource="arn:aws:s3:::bucket/patient-001.parquet",
action="read",
) as creds:
# creds scoped to exactly this object
process(creds)
# creds revoked (or expired) here| Provider | Install | Platform | Revocation | Regulated Use |
|---|---|---|---|---|
AWSSTSBroker |
pymayfly[aws] |
AWS / S3 | TTL only (900s min) | FedRAMP / HIPAA |
GCSBroker |
pymayfly[gcp] |
GCP / GCS | TTL only (15 min) | FedRAMP / HIPAA |
AzureBlobBroker |
pymayfly[azure] |
Azure / Blob Storage | TTL only (15 min) | FedRAMP / HIPAA |
VaultBroker |
Planned for 0.2.0 | Any | Explicit | Any |
SupabaseJWTBroker |
Planned for 0.2.0 | Postgres | Blocklist | Dev / test only |
| Metric | Traditional (bucket-wide role) | IPT |
|---|---|---|
| Blast radius | Entire data lake | Single object |
| Credential lifetime | Days / weeks | 900s |
| Post-deletion access | Credential still valid | Credential points at nothing |
| Audit granularity | Session-level | Transaction-level |
For a 1M-object data lake: blast radius reduced by 99.999%.
Subclass IdentityBroker and implement three methods:
from pymayfly import IdentityBroker, EphemeralCredential
class MyBroker(IdentityBroker):
def issue(self, transaction_id, resource, action) -> EphemeralCredential:
...
def revoke(self, credential) -> None:
...
def blast_radius(self, credential) -> str:
...See docs/providers.md for a provider walkthrough and
pymayfly/providers/aws_sts.py for a complete implementation.
This library implements the Identity-Per-Transaction protocol described in:
McKinnon, T. (2026). Zero-Trust Data Engineering: A Reference Architecture for Serverless, FedRAMP-High Healthcare Pipelines. IEEE BigDataSecurity 2026. TechRxiv preprint
Issues and PRs welcome. See CONTRIBUTING.md.
Provider contributions especially encouraged — if you implement a Vault or Supabase backend, open a PR. Use the new provider issue template.
Apache 2.0. See LICENSE.
Built and maintained by Deterministic Systems Lab.