Security and compliance
Written for the engineer implementing the integration and for the person who has to answer a security questionnaire about it. Both audiences need the same facts.
The trust boundary
Your backend ──client credentials──▶ PlaySpace API
│ ▲
│ mints │
▼ │
Session token ──▶ Browser ──▶ Cross-origin frame
Client credentials never enter a browser. They authorise everything your organisation can do. The browser-safe substitute is a session token: one person, one session, one role, fifteen minutes.
The frame is a real boundary. Nothing inside the surface can read your page, and nothing in your page can read a client's session. That is a property of the browser's origin model, not a convention we ask anyone to respect.
Your authorisation is the boundary we cannot see. PlaySpace verifies that a token's subject belongs to your organisation and that the session exists. It cannot verify that this browser should be that subject. The check in your token route is the whole of that decision.
Data we hold, and data we do not
We hold the name and date of birth you send, your identifier for each person, caregiver relationships, sessions and their durations, and every artifact produced — storybooks, worksheets, form responses, saved trays and boards, generated games and models. Where the notes capability is enabled, clinical notes written in PlaySpace.
We do not hold your schedule, your billing, your claims, your clinical notes, your documents, or any part of your record we did not produce. There is no import, no mirror and no nightly file.
Send the minimum. A first initial and a last initial are a complete and acceptable name. Date of birth is optional and used for age-appropriate content selection; omit it and a clinician sets the age band by hand.
Two rules the platform enforces on itself
No name and no free-text search term in a URL. Not a query string, not a path segment, in either direction. Person search is a POST with a body and there is no GET equivalent.
This is not fastidiousness. A platform's own request logs record path and query for every request, at a layer beneath any application-level protection. The only durable answer is to keep it out of the URL. That makes it a routing decision rather than a redaction one, which is why the interface is shaped the way it is.
Identifiers, not values, in every observable channel. Change-feed payloads, error documents, event payloads, download links and audit rows carry identifiers, statuses, counts, durations and enumerated values. Never a name, a date of birth, a page of story text, a form answer or a note body.
Please hold the same line. A requestId in a support ticket is useful; a client's name in one is a disclosure, and we will ask you to redact and resend.
Authentication and authorisation
Client credentials are long-lived, scoped, and exchangeable for a one-hour access token. Two can be live simultaneously, which is what makes zero-downtime rotation possible. Internet-protocol allowlisting is available and recommended: a leaked secret is useless off your network.
Scopes are fixed on the credential at approval. A call outside them returns 403 carrying both the required and granted lists, so the diagnosis is in the response.
Session tokens are minted per person per session per role, default fifteen minutes and maximum sixty. Three gates apply at mint and all three fail loudly: surfaces within the session's ceiling, origins a browser will honour as frame sources, and the organisation licensed for each surface.
Origins are validated at mint, not at frame load. An origin no browser will accept becomes a 422 naming the value. This converts the worst failure mode in embedded software — a silently blank rectangle — into an error message.
Revocation is immediate, per token or per session.
Isolation
Tenancy is enforced in the database, not in application code. Partner requests run under a role whose row-level policies key on the organisation claim in the token. A missing filter in application code cannot expose another organisation's data, because the policy is beneath it.
404 is deliberately ambiguous. Absent, archived, and belonging to another organisation return the same response. Distinguishing them is exactly the signal an enumeration attack needs.
Deletion is soft. Archiving makes a record unreadable to every reader, including exports. Nothing on the partner surface performs a hard delete.
Audit
Every request writes one audit row: the operation, the organisation, the acting subject, the resource identifiers touched, the outcome, and a request identifier. Rows are hash-chained, so a row cannot be altered or removed without breaking the chain.
Audit rows carry identifiers only. They are queryable by anyone with audit access, which is why they contain nothing that would be a disclosure to that reader.
Exports are audited additionally: who requested, on whose behalf, under which reason, and what was included.
The frame
No cookies. Session cookies are not sent into a cross-site frame; Safari blocks third-party storage and Chrome partitions it. The token lives in the frame's memory for the life of the document, which is why renewal is a callback rather than a refresh cookie.
frame-ancestors is set from the token's origins, so the browser refuses to render the surface anywhere you did not register. Set frame-src https://embed.playspace.health on your side and both directions are explicit — neither of us relies on the other getting it right.
Events crossing the channel are verified by source marker and origin. Anything else is dropped. Unknown event types are dropped rather than thrown on, so a host built against today's contract keeps working against a newer surface.
Generation and third-party models
Generation calls external model providers. Three things are true of every one of them:
A business associate agreement is in place with every provider in the generation path, covering the specific data flow.
Prompts carry what the clinician wrote. A clinician describing a child's situation to generate a storybook is sending that description to a model provider. That is inherent in the capability, it is covered by agreement, and it is worth your clinicians understanding.
Uploaded photographs are discarded after generation. An image used to produce a three-dimensional model is not retained, not used for training, and never appears in an export. The capability is for objects, pets and places; the documentation says so everywhere it appears, and your interface should too.
Nothing you send is used to train a model.
Regional handling
Data residency follows the clinic's country. A clinic in Canada has its data held in Canada; a clinic in the United States, in the United States. Some surfaces are regionally gated and fail closed where availability is not established, which is why country on a practitioner matters — omit it and the surface silently does not appear.
Cross-region access does not happen implicitly. An organisation operating in two regions holds two sets of data and can export each.
What we ask of you
- Store client credentials in a secret manager, not in a repository or an environment file that travels with one.
- Never ship a
pss_value to a browser. Search your built assets and confirm zero hits before going live. - Authorise the caller in your token route before minting. Derive
rolefrom your own record, never from a client-supplied parameter. - Rate-limit your token route. From an attacker's point of view it is an unauthenticated-adjacent surface.
- Deliver export bundles through your authenticated channel. The download link is credential-bearing — anyone holding it can retrieve the bundle while it is live. Do not email it.
- Keep client names out of your logs and out of support tickets. Send the
requestId.
Questionnaire answers
Short answers to what gets asked most.
Is PlaySpace HIPAA compliant? There is no such thing as HIPAA certification — no accreditation body issues one. The procurement-relevant fact is that PlaySpace executes a business associate agreement covering the data flows described here, and does so with every subprocessor in the generation path.
Where is data held? In the clinic's region. Canada and the United States today.
Is data encrypted? In transit with modern transport security, and at rest.
Do you train models on our data? No.
Can a partner read another partner's data? No, and the enforcement is in the database rather than in application code, so it does not depend on a query being written correctly.
What happens when we leave? One export call returns everything, in formats that need no PlaySpace software to open, at no charge. See Portability, and test it in the sandbox before you sign anything.
Do you have a penetration test report / audit report? Available under a mutual non-disclosure agreement from partner engineering.
How do we report a vulnerability? security@playspace.health. We acknowledge within one business day and will not pursue a good-faith reporter.