Connectors

Connect systems, with GDPR controls

AvailableFoundationmanifest

What it is for ​

Connect other systems to the instance and let people connect their own accounts, with the controls that support GDPR compliance built in. Nothing leaves or enters without a recorded legal basis and a field allowlist; personal data goes out as keyed pseudonyms unless you decide otherwise, the sensitive classes stay withheld, every flow is logged without its payload, and withdrawing consent disconnects the service and purges its credentials. A processing register for Article 30 is generated from the connections. It provides technical controls; it is not legal advice or a certification, and the catalogue says for every service how much of it is implemented.

What the package does and does not do ​

Connect external systems and let people connect their own accounts, with the controls that support GDPR compliance built in.

Models ​

connector_provider ​

A service or protocol a connection can use, from the catalogue shipped with obop

Read group: connectors.user. Write group: connectors.admin.

FieldKindData classPersonal dataGroupAgents seeDescription
nametextnonenoconnectors.userin clearName of the provider
categoryselect (generic, messaging, payments, developer, calendar_contacts, automation)nonenoconnectors.userin clearKind of service
maturityselect (working, generic_adapter, definition_only)nonenoconnectors.userin clearHow much of it exists: working, generic adapter or definition only
engineselect (webhook_out, webhook_in, rest_pull, csv_export, none)nonenoconnectors.userin clearThe generic engine that runs it
auth_kindselect (api_key, bearer_token, basic, oauth2, webhook_in, webhook_out, none)nonenoconnectors.userin clearHow the connection authenticates
directionselect (inbound, outbound, both)nonenoconnectors.userin clearWhether data flows in, out or both ways
max_classestextnonenoconnectors.userin clearData classes the provider may receive at most, comma separated
purposelongtextnonenoconnectors.userin clearWhat the provider is used for
descriptionlongtextnonenoconnectors.userin clearHow it works and what is tested
legal_nametextnonenoconnectors.userin clearLegal name of the recipient (sub-processor information)
countrytextnonenoconnectors.userin clearCountry of the recipient
dpa_urltextnonenoconnectors.userin clearWhere the provider publishes its data processing agreement
eu_adequateselect (yes, no, verify)nonenoconnectors.userin clearWhether transfers rest on EU or adequate-country processing: yes, no or verify with the provider
verify_notelongtextnonenoconnectors.userin clearWhat to confirm with the provider before relying on these facts
allowed_hoststextnonenoconnectors.userin clearHosts the provider connects to, comma separated; empty means the connection names its own
config_fieldslongtextnonenoconnectors.userin clearSettings and credentials the provider needs, as a JSON list
setuplongtextnonenoconnectors.userin clearSetup instructions
webhook_schemeselect (standard, github, stripe)nonenoconnectors.userin clearSignature scheme of inbound webhooks
oauth_scopestextnonenoconnectors.userin clearOAuth scopes requested, for OAuth providers
enabledboolnonenoconnectors.userin clearAn administrator enabled the provider
users_may_useboolnonenoconnectors.userin clearPeople may connect their own accounts with it
dpa_recordedboolnonenoconnectors.userin clearThe agreement with the provider is recorded
legal_basisselect (consent, contract, legitimate_interest, legal_obligation)nonenoconnectors.userin clearLegal basis the administrator set for this provider
legal_basis_textlongtextnonenoconnectors.userin clearText shown to people when they are asked for consent

provider_policy ​

What an administrator decided about one provider: enabled, for whom, legal basis, agreement and OAuth client

Read group: connectors.admin. Write group: connectors.admin.

FieldKindData classPersonal dataGroupAgents seeDescription
providertextnonenoconnectors.adminin clearId of the provider this policy is for
enabledboolnonenoconnectors.adminin clearThe provider may be connected at all
users_may_useboolnonenoconnectors.adminin clearPeople with connectors.user may connect their own accounts
allowed_grouptextnonenoconnectors.adminin clearPermission group that may use it; empty means connectors.user
legal_basisselect (consent, contract, legitimate_interest, legal_obligation)nonenoconnectors.adminin clearLegal basis recorded for connections of this provider
legal_basis_textlongtextnonenoconnectors.adminin clearText shown to people when they are asked for consent
dpa_recordedboolnonenoconnectors.adminin clearA data processing agreement with the provider is in place
dpa_referencetextnonenoconnectors.adminin clearWhere the agreement is kept or its reference
default_policylongtextnonenoconnectors.adminin clearPolicy JSON that new connections of this provider start with
oauth_client_idtextinternalnoconnectors.adminin clearOAuth client id you registered with the provider
oauth_client_secretlongtextsecretnoconnectors.adminwithheldOAuth client secret; write-only, stored encrypted

connection ​

A link to one external system, with its credentials, field allowlist, policy and state

Read group: connectors.user. Write group: connectors.user.

FieldKindData classPersonal dataGroupAgents seeDescription
nametextnonenoconnectors.userin clearA name that tells you what the connection is for
providertextnonenoconnectors.userin clearId of the provider from the catalogue
owner_scopeselect (instance, user)nonenoconnectors.userin clearWhether the connection belongs to the instance or to one person
owner_usertextinternalyesconnectors.usermaskedThe person who owns the connection
owner_groupstextnonenoconnectors.adminin clearPermission groups the owner held when the connection was last changed
stateselect (draft, connected, paused, error, revoked)nonenoconnectors.userin clearWhere the connection is: draft, connected, paused, error or revoked
configlongtextnonenoconnectors.userin clearNon-secret settings as a JSON object
credentialslongtextsecretnoconnectors.userwithheldCredentials as a JSON object; write-only, stored encrypted, never returned
credentials_hinttextnonenoconnectors.userin clearWhether credentials are set, with at most the last four characters
oauth_tokenslongtextsecretnoconnectors.userwithheldOAuth tokens; write-only, stored encrypted, never returned
field_allowlistlongtextnonenoconnectors.userin clearFields that may leave or be accepted, as a JSON object of model to field names; empty means nothing
policylongtextnonenoconnectors.userin clearTreatment overrides by class or field and impact-assessment acknowledgements, as JSON
rate_limit_per_hournumbernonenoconnectors.userin clearMost flows per hour
volume_cap_per_daynumbernonenoconnectors.userin clearMost records per day
retention_daysnumbernonenoconnectors.userin clearDays flow logs and runs are kept
created_attextnonenoconnectors.userin clearWhen the connection was created
last_sync_attextnonenoconnectors.userin clearWhen the connection last ran
last_errortextnonenoconnectors.userin clearSummary of the last failure, without payloads
resultlongtextnonenoconnectors.userin clearOutput of the last command (test, sync, authorisation link); never stored

The legal basis recorded for a connection: who, why, which data classes, and whether it was withdrawn

Read group: connectors.user. Write group: connectors.user.

FieldKindData classPersonal dataGroupAgents seeDescription
connectionref → connectionnonenoconnectors.userin clearThe connection this basis is for
owner_usertextinternalyesconnectors.usermaskedOwner of the connection
stateselect (active, withdrawn, superseded)nonenoconnectors.userin clearactive, withdrawn, or superseded by a newer record
subject_kindselect (user, party, instance)nonenoconnectors.userin clearWhose basis it is: a user, a party or the instance
subjecttextinternalyesconnectors.usermaskedId of the party when the subject is a party
given_bytextinternalyesconnectors.usermaskedWho recorded it
purposelongtextnonenoconnectors.userin clearThe purpose the data is processed for
legal_basisselect (consent, contract, legitimate_interest, legal_obligation)nonenoconnectors.userin clearconsent, contract, legitimate interest or legal obligation
notelongtextnonenoconnectors.userin clearExplanation; for legitimate interest the balancing test
classestextnonenoconnectors.userin clearData classes that may flow under this record, computed from the connection
fields_summarylongtextnonenoconnectors.userin clearModels and fields that may flow, computed from the connection
recorded_attextnonenoconnectors.userin clearWhen it was recorded
withdrawn_attextnonenoconnectors.userin clearWhen it was withdrawn, if it was
withdrawn_bytextinternalyesconnectors.usermaskedWho withdrew it

sync_run ​

One run of a connection: when, how many records, and how it ended; never the data

Read group: connectors.user. Write group: connectors.admin.

FieldKindData classPersonal dataGroupAgents seeDescription
connectionref → connectionnonenoconnectors.userin clearThe connection that ran
owner_usertextinternalyesconnectors.usermaskedOwner of the connection
directionselect (inbound, outbound)nonenoconnectors.userin clearWhether data went out or came in
kindselect (manual, event, pull, webhook, test)nonenoconnectors.userin clearWhat started it
started_attextnonenoconnectors.userin clearWhen it started
finished_attextnonenoconnectors.userin clearWhen it ended
statusselect (running, succeeded, partial, failed, retrying, dead_letter)nonenoconnectors.userin clearHow it ended
recordsnumbernonenoconnectors.userin clearRecords sent or accepted
rejectednumbernonenoconnectors.userin clearRecords refused
proposednumbernonenoconnectors.userin clearChanges held for approval
error_summarytextnonenoconnectors.userin clearWhy it failed, without payloads

data_flow_log ​

Append-only record of every flow: when, what, how many, which fields, how treated, and a hash of the payload; never the payload

Read group: connectors.user. Write group: connectors.admin.

FieldKindData classPersonal dataGroupAgents seeDescription
connectionref → connectionnonenoconnectors.userin clearThe connection the flow belongs to
owner_usertextinternalyesconnectors.usermaskedOwner of the connection
attextnonenoconnectors.userin clearWhen it happened
directionselect (outbound, inbound)nonenoconnectors.userin clearWhether data went out or came in
modeltextnonenoconnectors.userin clearThe model the records belong to
record_countnumbernonenoconnectors.userin clearHow many records
fields_senttextnonenoconnectors.userin clearFields that left or were accepted, comma separated
fields_deniedtextnonenoconnectors.userin clearFields the policy withheld, comma separated
masking_modetextnonenoconnectors.userin clearTreatments applied, for example pseudonymise=2;allow=1
payload_hashtextnonenoconnectors.userin clearSHA-256 of the payload after treatment
outcomeselect (released, received, refused, rejected, erased)nonenoconnectors.userin clearreleased, received, refused, rejected or erased
reasontextnonenoconnectors.userin clearWhy a flow was refused or a record rejected

processing_register ​

The record of processing activities (GDPR Article 30) generated from the connections; exportable as CSV

Read group: connectors.admin. Write group: connectors.admin.

FieldKindData classPersonal dataGroupAgents seeDescription
connectionref → connectionnonenoconnectors.adminin clearThe connection this row describes
nametextnonenoconnectors.adminin clearName of the connection
statetextnonenoconnectors.adminin clearState of the connection
owner_scopetextnonenoconnectors.adminin clearInstance or user
owner_usertextinternalyesconnectors.adminmaskedOwner of the connection
providertextnonenoconnectors.adminin clearProvider id
recipientlongtextnonenoconnectors.adminin clearWho receives the data (legal name)
recipient_countrytextnonenoconnectors.adminin clearWhere the recipient is
purposelongtextnonenoconnectors.adminin clearPurpose of the processing
legal_basistextnonenoconnectors.adminin clearRecorded legal basis
consent_recorded_attextnonenoconnectors.adminin clearWhen the basis was recorded
data_subjectslongtextnonenoconnectors.adminin clearCategories of data subjects
personal_data_categorieslongtextnonenoconnectors.adminin clearCategories of personal data, with class and treatment
transfer_basislongtextnonenoconnectors.adminin clearBasis for transfers to third countries
agreement_recordedtextnonenoconnectors.adminin clearWhether the agreement with the recipient is recorded
retention_daystextnonenoconnectors.adminin clearRetention of logs, in days
safeguardslongtextnonenoconnectors.adminin clearTechnical and organisational measures
csvlongtextnonenoconnectors.adminin clearThe register as CSV; filled by the export command, never stored

egress_policy ​

Instance-wide switches for data flows: the master switch, EU-only providers, the agreement requirement and the host allow-list

Read group: connectors.admin. Write group: connectors.admin.

FieldKindData classPersonal dataGroupAgents seeDescription
flows_enabledboolnonenoconnectors.adminin clearMaster switch: when off nothing leaves and nothing is accepted
eu_onlyboolnonenoconnectors.adminin clearPersonal data only goes to providers with an EU or adequacy basis
require_dpaboolnonenoconnectors.adminin clearPersonal data, even pseudonymised, only goes to providers whose agreement is recorded
host_allowlisttextnonenoconnectors.adminin clearHosts connections may reach, comma separated; empty means no extra restriction
default_retention_daysnumbernonenoconnectors.adminin clearRetention for logs of connections that no longer exist
resultlongtextnonenoconnectors.adminin clearOutput of the last command (checklist, purge); never stored

privacy_preview ​

What a sample outbound record looks like after the policy: the exact payload and the treatment of each field

Read group: connectors.user. Write group: connectors.user.

FieldKindData classPersonal dataGroupAgents seeDescription
providertextnonenoconnectors.userin clearProvider the preview is for
connectiontextnonenoconnectors.userin clearAn existing connection to preview, instead of a provider
target_modeltextnonenoconnectors.userin clearThe model to preview
record_idtextnonenoconnectors.userin clearA record to use as the sample; empty means the first one
field_allowlistlongtextnonenoconnectors.userin clearFields to include, as a JSON object of model to field names
policylongtextnonenoconnectors.userin clearPolicy JSON to preview
payloadlongtextnonenoconnectors.userin clearThe payload after treatment, as JSON; never stored
treatmentslongtextnonenoconnectors.userin clearEach field with its class and treatment, as JSON; never stored

Workflows ​

connection ​

ActionMovesWho may run itApproval
connection.connectstate: draft → connectedconnectors.useryes
connection.pausestate: connected → pausedconnectors.useryes
connection.resumestate: paused → connectedconnectors.useryes
connection.retrystate: error → connectedconnectors.useryes
connection.revokestate: * → revokedconnectors.useryes
connection.test-connectors.userno
connection.sync-connectors.useryes
connection.oauth_start-connectors.userno
ActionMovesWho may run itApproval
consent.withdrawstate: active → withdrawnconnectors.useryes

processing_register ​

ActionMovesWho may run itApproval
processing_register.export_csv-connectors.adminno

egress_policy ​

ActionMovesWho may run itApproval
egress_policy.checklist-connectors.adminno
egress_policy.purge-connectors.adminyes

privacy_preview ​

ActionMovesWho may run itApproval
privacy_preview.render-connectors.userno

Permission groups ​

Groups used by this app:

  • connectors.admin
  • connectors.user

Approval steps ​

Steps an agent can only propose:

  • connection.connect
  • connection.pause
  • connection.resume
  • connection.retry
  • connection.revoke
  • connection.sync
  • consent.withdraw
  • egress_policy.purge

What agents can and cannot do ​

An agent can read, search, create and update records of this app, and run the actions that need no approval, within the permission groups of its token.

It can only propose these steps, and a person must approve them: connection.connect, connection.pause, connection.resume, connection.retry, connection.revoke, connection.sync, consent.withdraw, egress_policy.purge, connector_provider.delete, provider_policy.delete, connection.delete, consent.delete, sync_run.delete, data_flow_log.delete, processing_register.delete, egress_policy.delete, privacy_preview.delete.

Personal data is masked as placeholder tokens: connection.owner_user, consent.owner_user, consent.subject, consent.given_by, consent.withdrawn_by, sync_run.owner_user, data_flow_log.owner_user, processing_register.owner_user.

These fields are withheld from agents entirely: provider_policy.oauth_client_secret, connection.credentials, connection.oauth_tokens.

Dependencies ​

None.

Install ​

Built in. It is available in every instance and cannot be removed.

Build your own ​

The module guide shows how apps like this one are written