Everything that processes customer data. Your own client can object to any of these, so the list is complete rather than convenient. We give 30 days' notice before adding one.
| Who | What for | Where | What they can see |
|---|---|---|---|
| LinkedIn (Microsoft) | publishing, and the analytics read back | global | the posts you publish and the pages you connect |
| [hosting provider] | runs the application and the database | [region] | everything, encrypted at rest |
| [mail provider] | invitations and notifications | [region] | recipient addresses and message contents |
| [model provider] | drafting and research, where you use it | [region] | the briefs and drafts you send it, never LinkedIn member data |
These are the values the code enforces, not a policy written
beside it. Deletion runs on a schedule; /api/retention shows
whether anything is overdue, and it is readable by any signed-in customer.
| What | Kept | Why that long |
|---|---|---|
| li_actors | 1 days | other members' profile data — cache only |
| resets | 1 days | password reset links — a way into an account, held for hours and deleted within a day |
| li_member_activity | 2 days | member social activity |
| li_comments | 6 weeks | organization social activity |
| li_mentions | 6 weeks | organization social activity |
| li_org_profile | 8 weeks | organization profile data, authenticated |
| li_deliveries | 2 months | webhook de-duplication, our own |
| li_stats | 1 year | page admin and reporting data |
| li_member_stats | 1 year | the authenticated member's own data |
| enquiries | 2 years | the client's own enquirers, in their own words — their commercial record, kept two years so a year-on-year comparison is possible, then gone |
| voice_vetoes | 2 years | a person saying a draft did not sound like them, with their name. Two years: after that the record it fed into is the thing that matters, not the objection |
| sign_offs | 7 years | who approved what, with the address it came from. Seven years, because the question an approval answers is asked long after the fact and a regulated client's retention obligation is usually six |
| claims | — | which figure in which post rests on which source. Ours, about our own posts, and the thing the report cites. |
| expectations | — | what was agreed with a client and when. A name is stored because 'agreed with somebody' answers nothing, and it is deleted with the account. |
| li_cursor | — | our own bookkeeping — where each pull got to. No LinkedIn data: timestamps and URNs we already hold, and a URN may be kept without limit. |
| li_hooks | — | our own webhook registrations: an organization URN, an event name and our callback URL. A URN may be kept without limit, and a registration that expired silently is deleted when the destination is disconnected, not on a clock. |
| post_versions | — | every version of our own copy, with who changed it. Our work product, and the answer to what a post said when it was approved. |
| proposals | — | what we recommended and what the client decided. The record that answers 'you never brought us ideas'. |
| sources | — | a web address, a publisher, a date and a sentence quoted from a public page. No personal data, and deleting it would break the citation on a post that is still live. |
| voice_records | — | how a brand argues, what it refuses to say, what is off limits. Configuration, written by the account itself. |
Two consequences worth stating. A comment and the person who wrote it have different clocks — the comment is organization activity at six weeks, the commenter's name is another member's profile data at twenty-four hours — so after a day a comment is still there and its author reads as "A LinkedIn member". And LinkedIn's terms do not permit member data to leave the application, including to you: client reports are built from aggregates, and the export path refuses to render a structure containing a name.
Each of these is something the test suite exercises, not an intention.
Sealed before they reach the database and authenticated on read, so a tampered row fails loudly rather than decrypting to nonsense. A stolen copy of the database is not a stolen set of LinkedIn accounts.
Salted per user, n=2^14. Not recoverable by us. A wrong password and a missing account take the same time, so neither can be told from the other.
Every account's reach is computed by a single function and every route asks it. The test suite enumerates every route the application exposes and attacks each one with an identity that must not reach it — a route added later without a check fails without anyone remembering to test it.
An account you may not see and an account that does not exist return the same status and the same words.
Nothing in the system updates or deletes an audit row. Who approved, connected, changed or erased what, and from which address.
On the address and on the network address separately, so one attacker cannot lock every account out and a botnet cannot walk through.
A session cookie that is HttpOnly and SameSite=Lax, and an origin check on every state-changing request.
A row filtered out of a query is still a row in the file. The retention sweep deletes, and /api/retention shows whether anything is overdue.
As a processor to you, and a sub-processor where you are acting for your own client.
| Categories of data subject | Staff of the agency; staff of the agency's client brands; LinkedIn members who comment on or mention a published post |
| Categories of personal data | Name, business email address, role, hashed password, last sign-in; authored post content; LinkedIn access tokens; for commenters, the name, headline and photograph LinkedIn returns |
| Special category data | None. Do not put any into a post. |
| Purpose | Scheduling and publishing content to LinkedIn on the controller's documented instruction, and reporting on it |
| Recipients | LinkedIn; the sub-processors listed above; nobody else |
| Transfers | [mechanism — SCCs Module 2 plus a transfer impact assessment] |
| Retention | As set out in the table above. Erasure is a button and it deletes, including files on disk |
| Security | As set out below |
A trust page that only lists strengths is a trust page nobody believes. These are the gaps, and when each would be worth closing.
None is held today. For UK and EU buyers Cyber Essentials Plus is the usual ask and is days rather than months; it is the one we would pursue first, at around ten customers. SOC 2 Type II is 12–18 months end to end and worth starting only when a named deal depends on it.
There is no measured operating history to commit against, and a service credit is cheap while a broken promise is not. This will be offered once there is a quarter of real numbers behind it.
Not yet commissioned. The isolation suite is adversarial and mutation-tested, which is not the same thing and is not offered as if it were.
Everything is written from LinkedIn's documentation and proven against a test double. The Standard tier application has not yet been made.
One, called session. It is what keeps you signed in: HttpOnly,
SameSite=Lax, twelve hours. There are no analytics or advertising cookies and no
third-party trackers, which is why there is no cookie banner.
We will tell affected accounts and, where required, the supervisory authority within 24 hours of becoming aware — tighter than the 72 hours a controller owes a regulator, because you need time to make your own notification. We will say what we know even where that is not yet everything.
Security questionnaires: send CAIQ Lite or SIG Lite to [security contact] and we will return it within five working days. Data protection: [privacy contact]. The data processing addendum is at /dpa.
Assembled with the help of a language model. Check each figure against the source shown beside it before acting on it.