Add a third-party service¶
Data leaving the project to another organisation — a geocoder, a payment provider, an email/SMS service, analytics, an error tracker, a CRM — is a transfer. It needs a party and a declaration on every touchpoint that sends.
1. The party¶
compliance/parties/<id>.yaml (kebab-case id):
name: HubSpot, Inc.
country: US
address: 25 First Street, Cambridge, MA 02141, USA
email: privacy@hubspot.com
website: https://www.hubspot.com
hosts: [api.hubapi.com] # API hostnames the code calls, when they differ from the website
dpa: https://legal.hubspot.com/dpa
safeguard: dpf # outside the EEA/adequate countries: dpf | sccs | bcr | derogation
dpf_certified: true # with dpf: checked on the DPF list
country decides Chapter V: an adequate country (the EEA, the UK,
Switzerland, Japan…) needs no safeguard; the US needs dpf with
dpf_certified: true, or sccs. A party with a country and no valid
safeguard makes every transfer to it a finding. Address and email may be
!todo while you look them up.
The reviewer agents create parties too (party_add) when they meet a new
SDK or host, with !todo contact details; you complete them.
2. The transfer¶
On each touchpoint that sends, in <unit>/compliance/touchpoints/<slug>.yaml:
transfers:
- party: hubspot
data: [api:people.User.email, api:people.User.phone, api:geo.Address.position]
purpose: CRM contact for the "customers near you" campaign
or through the tools: touchpoint_set_data with transfers (the agent
does this), touchpoints set-data on the CLI.
3. What follows automatically¶
- The flow
api:checkout->party:hubspotappears inflows list --kind transfer, with the country and whether it is safeguarded. - Its disclosure/credential threats are dismissed by the
declared_transferrule: sending the data there is the intended use. Whether it sends more than declared is the reviewer's question at declaration time. - The activity the touchpoint belongs to lists the party under recipients.
- If the code stops calling the host, nothing happens; if it starts calling
a host no party owns,
flow-undeclared.
Not a third party: a service the project runs¶
Do not invent a party for the project's own realtime server, search index
or the SMTP relay behind EMAIL_HOST — a party is a named organisation. Those
are stores: declare one in <unit>/compliance/stores/<slug>.yaml
type: realtime # or external, search, ...
backend: hocuspocus
name: TMW kitchen board
hosts: [TMW_URL] # the setting name or hostname the code reaches it by
(or store_add from the agent) and put the copy on the touchpoint:
stores:
- store: tmw
data: [api:orders.Order.reference, api:orders.Order.status]
purpose: live kitchen board
The flow api:task:kitchen.sync_order_to_board->api:tmw is a store flow
with the store's threat cells; nothing enters the recipients column. When
the operator is a deployment fact (the SMTP relay), type: external and
provider: !todo for a human.
Hosts and the project's own¶
The introspection reads the hostnames in the view's URL literals and
well-known SDK client names. Hosts from ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS,
CORS_ALLOWED_ORIGINS and any *_URL setting are the project's own, as
are docker service names and loopback. A settings.X_URL / X_HOST the
view reads is reported as setting:X_URL. Everything else must belong to a
party (its website domain or hosts list) or to a store (hosts, which
may name the setting).