You opened an AI chat transcript, an agent log, or an API response and found a token like <private_address>, <private_person>, or <pl:aws-access-key:1> sitting where a real value should be. A redaction layer put it there. It found something sensitive and swapped in a label before the text reached the model or the log you are reading.
This page decodes the common placeholder vocabularies and tells you which tool emits each one.
Quick decode
| You see | It means | Emitted by |
|---|---|---|
<private_person> | A person’s name was removed | OpenAI Privacy Filter |
<private_address> | A postal address was removed | OpenAI Privacy Filter |
<private_email> | An email address was removed | OpenAI Privacy Filter |
<pl:aws-access-key:1> | An AWS access key (the 1st in this request) | Pipelock |
<pl:email:2> | An email address (the 2nd in this request) | Pipelock |
[REDACTED] / [REDACTED: PatternName] | A value matched a secret pattern and was masked | Pipelock |
The original value is not in the text you have. Redaction runs before the text is forwarded or stored, and the placeholder carries the type, not the data.
The <private_*> family: OpenAI Privacy Filter
The lowercase, angle-bracketed tokens like <private_address> are what OpenAI’s Privacy Filter emits (announcement). It is an open-weight PII detection model that classifies spans of text into eight categories and replaces each span with a bracketed label. The categories it detects are account numbers, addresses, emails, names, phone numbers, URLs, dates, and secrets. The labels you are most likely to run into:
| Placeholder | Removed value |
|---|---|
<private_person> | A person’s name |
<private_address> | A postal address |
<private_email> | An email address |
<private_url> | A URL |
<private_date> | A date tied to a person |
<account_number> | An account number |
Any other bracketed label you see follows the same idea: a category name standing in for a removed value. The redaction is irreversible from the output alone, and the original value is not encoded anywhere in the token.
The <pl:CLASS:N> family: Pipelock
Pipelock is an open-source agent firewall. When it detects a secret in agent traffic and the policy is to redact rather than block, it rewrites the value in place as <pl:CLASS:N>:
CLASSis the secret type (for examplegithub-token,email,ipv4).Nis a per-request counter. The first email is<pl:email:1>, the second is<pl:email:2>.- Numbering restarts at 1 per class on every request, so nothing in the placeholder ties one request to another. The model keeps type information; it gains no way to correlate values across calls.
Pipelock’s built-in classes:
| Category | Classes |
|---|---|
| Network | ipv4, ipv6, cidr, fqdn, mac |
| Identity / PII | email, ssn, credit-card, ad-user, seed-phrase |
| Cloud & infra keys | aws-access-key, google-api-key, hashicorp-vault-token, databricks-token, supabase-service-key |
| Source control & registries | github-token, gitlab-token, npm-token, pypi-token |
| Model & AI providers | openai-api-key, anthropic-api-key, fireworks-api-key, huggingface-token, replicate-api-token, together-ai-key |
| SaaS tokens | slack-token, vercel-token, linear-api-key, notion-api-key, sentry-auth-token, telegram-bot-token, discord-bot-token |
| Crypto material | jwt, ssh-private-key, hash-md5, hash-sha1, hash-sha256, hash-sha512 |
| Generic | env-secret |
Some labels (aws-secret-key, bearer, hash-ntlm, credential, known-secret) are reserved for future detection profiles and are not matched by the built-in patterns yet.
Pipelock also uses a flat mask in its response path: [REDACTED] on its own, or [REDACTED: PatternName] when the matching pattern is named. That form drops the type. The <pl:CLASS:N> form keeps it.
Why typed placeholders instead of one blank token
A generic mask tells the model that something was here. A typed placeholder tells it what kind of thing was here, without handing over the value. An agent reading <pl:github-token:1> can still reason about the request shape. The same agent reading [REDACTED] loses that. Pipelock defaults to the typed form for exactly that reason, and it numbers per request so two removed values stay distinguishable while staying uncorrelated across calls.
If you run Pipelock and want the full picture of how redaction is configured and where it sits in the scanner pipeline, see AI agent data redaction. For the broader model of inspecting and proving what an agent sent, see verifiable egress control.