GDPR Article 5(1)(b) — the purpose limitation principle — is the GDPR clause most hand-rolled compliance implementations get wrong. The principle is short: personal data shall be “collected for specified, explicit and legitimate purposes and not further processed in a manner that is incompatible with those purposes.”
Translated for agent builders: the data flowing through this agent invocation must be used only for the purpose for which it was collected. The model picks a tool. The tool’s purpose must match. If it doesn’t, the tool dispatch is not lawful under Article 5(1)(b) and the agent must deny it.
That’s a runtime check. Not a Confluence page.
What goes wrong with the PDF approach #
The common hand-rolled approach is:
- A privacy policy document declaring purposes (“We collect data to provide our service, for analytics, and for legal compliance”).
- A consent management module capturing the user’s tickbox.
- Trust in the application code to “do the right thing” with the data.
This is fine for traditional software, where the developer knows what each function call does and writes code to enforce the policy manually. For agents it breaks. The model picks the tool. The model doesn’t know the purpose taxonomy. Without runtime enforcement at the tool dispatch, the agent can make any tool call the model wants — including ones outside the declared purpose.
What the runtime check looks like #
The check has three parts.
Part 1: the Principal carries the purpose claim #
Your IdentityAdapter mints a Principal at the trust boundary. The
Principal must carry a purpose claim. For an OIDC token, the
claims look like this — an ISO 8601 issued-at, an explicit purpose
value, a lawful basis reference:
sub— subject IDpurpose— one of a finite set, e.g.CREDIT_DECISIONtenant— multi-tenant contextlawful_basis—art-6-1-b-contract,art-6-1-a-consent, etc.iat,exp— timestamps
The purpose value comes from your Records of Processing Activities
(RoPA). It’s not free-form.
Part 2: the agent is registered with a purpose #
Every agent is registered in the model registry with the purposes it’s authorised to serve:
regulus:
agents:
- name: credit-decision-agent
purposes: [CREDIT_DECISION, FRAUD_REVIEW]
data-categories: [financial, identity]
An invocation with purpose=MARKETING_AUTOMATION on this agent fails
at the BeforeAgentCallback — the purpose isn’t in the agent’s
authorised set.
Part 3: each tool has a purpose attribution #
Tools register their compatible purposes via Java annotations: the
@Tool annotation includes purposes = "CREDIT_DECISION" and
dataCategories = "financial". The BeforeToolCallback checks: does
the calling Principal’s purpose intersect with this tool’s authorised
purposes, and does it intersect with the agent’s registered
purposes? If either check fails, DENY.
The decision flow at runtime #
Pseudocode for the check (the real implementation lives in
RegulusPolicyPlugin.beforeToolCallback):
- Read invocation purpose from
ctx.getPrincipal().getPurpose(). - Read agent purposes from the registered agent.
- Read tool purposes from the registered tool.
- If invocation purpose is not in both sets, emit a DENY event with
the clause text
gdpr:Article-5(1)(b)and the framework citation. - Otherwise, ALLOW and proceed to the dispatch.
The DENY emission is the substantive evidence. Filter the audit chain
by clause LIKE 'gdpr:Article-5(1)(b)%' to produce the runtime
evidence of enforcement.
What an auditor will look for #
In a real DPO walkthrough, the questions you’ll see:
- “Show me your purpose taxonomy.” Your RoPA defines the finite set of purposes. The Regulus agent registry pins them.
- “Show me a denied tool call due to purpose mismatch.” Filter the chain. Pick one. Show the principal’s purpose, the agent’s purposes, the tool’s purposes, the clause.
- “How do you handle Article 5(1)(b)‘s ‘compatibility’ exception?” Article 5(1)(b) allows further processing for “archiving in the public interest, scientific or historical research purposes or statistical purposes” as compatible. If your agent has any such use case, the purpose taxonomy needs to include it and the compatibility test needs to be documented.
- “What happens to events emitted under a withdrawn consent?” Article 7(3) — consent can be withdrawn. Your audit chain continues to record events as historical artefacts (lawful for the period when consent was valid); future invocations against a Principal with withdrawn consent fail at the policy plugin.
The hard part isn’t the runtime #
The runtime is the easy part. The hard part is the purpose taxonomy itself. Most organisations have a vague RoPA with broad purposes like “service delivery” that don’t constrain anything meaningful. Building a useful purpose taxonomy — finite, mutually exclusive, exhaustive — is a 4–6 week exercise with your DPO.
Once you have the taxonomy, Regulus’s runtime enforcement is one config block. The taxonomy is the work; the runtime is the delivery mechanism.
For the broader GDPR landscape, see the GDPR profile page. For the wider EU AI context, see Article 9 in code.