Agent Wranglers

CMP-68Required

Split the duties in writing with joint controllers

When you and another company decide together why and how personal data is used, sign an arrangement that splits the GDPR duties. Show its essence to the people affected.

How to do it

GDPR Article 26 makes you joint controllers. Common cases are a co-branded product, a shared loyalty scheme, or a social media plugin that sends visitor data to its owner. On a website, load such plugins only after a click, as load embedded videos and maps only after a click says. The arrangement says who answers data requests, who gives the privacy notice and who reports breaches. It may name one contact point for people. People can still use their rights against either of you, whatever the arrangement says. Record each partner in the vendor register with the role joint_controller. Link it from the record of processing. A vendor that only follows your instructions is a processor and needs an Article 28 agreement instead.

Examples

YAML example

- id: partner-loyalty
  name: Example Rewards AB
  role: joint_controller
  arrangement: contracts/2026-06-example-rewards-joint-control.pdf
  duties:
    data_requests: us
    privacy_notice: us
    breach_reports: partner
  contact_point: privacy@example.com

JavaScript example

const JOINT_DUTIES = ['data_requests', 'privacy_notice', 'breach_reports'];

export const jointControllerProblems = vendor => vendor.role !== 'joint_controller' ? [] : [
  ...(vendor.arrangement ? [] : [`${vendor.id}: no arrangement`]),
  ...JOINT_DUTIES.filter(duty => !vendor.duties?.[duty]).map(duty => `${vendor.id}: no owner for ${duty}`),
];

Python example

JOINT_DUTIES = ["data_requests", "privacy_notice", "breach_reports"]

def joint_controller_problems(vendor: dict) -> list[str]:
    if vendor.get("role") != "joint_controller":
        return []
    problems = [] if vendor.get("arrangement") else [f"{vendor['id']}: no arrangement"]
    duties = vendor.get("duties") or {}
    return problems + [f"{vendor['id']}: no owner for {duty}" for duty in JOINT_DUTIES if not duties.get(duty)]

How to check

The build fails when a register entry with the role joint_controller lacks an arrangement link or an owner for data requests, notices and breaches. A test fetches the privacy policy and finds each joint controller's name.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/compliance/processors-and-transfers/joint-controllers">Agent Wranglers compliance playbook</a>. In code you write, add a comment next to it with the same link.