Support access security
Ce contenu n’est pas encore disponible dans votre langue.
In short
Section titled “In short”On the hosted service, the people who run SpeculaPro have no standing access to what is inside a workspace. Their own console shows a workspace’s name, plan, usage counts and health, never its cases, alerts, customers or transactions. The one way a member of staff looks inside a workspace is a support session, and it exists only under these conditions:
- A member of staff asks, with a written reason, a scope and a duration.
- Someone in the workspace approves, and may narrow the scope and shorten the time.
- The member of staff opens a session through a one-time link good for one minute.
- The session is read-only, limited to the scope, and checked against the approval on every request.
- Every read, and every refused attempt, is written to the workspace’s audit log and the provider’s.
- The workspace can revoke at any moment.
A self-hosted installation has no provider and no support sessions: the endpoints that open one answer nothing useful there, and the Settings tab says so.
How to use it day to day is in Support access.
The life of a request
Section titled “The life of a request”| Step | Who | What is checked |
|---|---|---|
| Request | A member of SpeculaPro’s staff, signed in to the provider console with two-factor authentication | A reason of at least 20 characters; a scope; a duration from 15 minutes to 8 hours. The workspace must be active. The workspace’s policy must accept requests, allow the scope asked for and allow the duration. At most 10 requests can wait for one workspace, and a member of staff can have one open request per workspace. A request the policy refuses reaches nobody in the workspace |
| Notice | SpeculaPro | Everyone in the workspace holding support_access.manage is notified, with who asks and for how long |
| Decision | Someone in the workspace holding support_access.manage |
The permission is checked by the application and again inside the database function that records the decision. The scope can be narrowed, not widened. The duration can be shortened (to 5 minutes at least), not extended. Full read can be given only if the policy allows it |
| Lapse | Nobody | A request nobody decides lapses after 72 hours |
| Handoff | The same member of staff | The console issues a link whose token works once, within 60 seconds, only while the approval runs, the workspace is active and the member of staff still is one. The token travels in the address’s fragment, which browsers don’t send to servers or write to access logs. A link that fails says nothing about why |
| Session | The same member of staff | See below |
| End | Either side, or the clock | The approval’s time runs out, the workspace revokes, or the provider gives it back. Its sessions end in the same step |
The workspace’s policy (accept requests at all, the longest access, whether full read may be given) is the workspace’s own setting. Tightening it applies at once. Loosening it goes through maker-checker where the workspace’s approval policy covers Security settings.
What a support session is
Section titled “What a support session is”A support session is not a user of the workspace. Nobody can sign in as it, give it a role, assign it a case or make it the author of anything.
| Property | How it is enforced |
|---|---|
| Read-only | Every request that isn’t a GET or HEAD is refused, whatever the route. The single exception is the session’s own sign-out |
| Closed by default | A read is served only if its route is on an explicit list with the scope it needs. A route that isn’t listed is refused, so a new endpoint is closed to support sessions until someone classifies it. A test walks every route of the API and fails the build if one is unclassified |
| Two locks | Besides the route list, the session holds a fixed set of view permissions for its scope and nothing else, and the ordinary permission checks apply to it as to everyone |
| Checked every time | The approval, the workspace’s status and the member of staff’s status are read from the database on every request, with no cache. A revoked or expired approval, a suspended workspace or a deactivated member of staff stops the very next request |
| Recorded before served | Each read is written to both audit logs first. A read that can’t be recorded is refused |
| Filtered | Answers pass through the tipping-off filter described below. An answer that can’t be filtered is refused |
| Its own cookie | __Host-sp_support (sp_support when SP_SECURITY_COOKIE_SECURE=false): HttpOnly, SameSite=Strict, expiring with the approval. It is separate from a person’s session cookie, and a request carrying it takes no Authorization header |
| Protected personal data stays masked | No scope includes entities.view_pii, so ID numbers, phone numbers, email addresses, dates of birth and full account numbers show masked, as they do for an analyst or auditor without that permission. Customer names are not masked: under full read, support sees them |
| Stays in its region | An approval is a record of the region it was made in. It is not carried when a workspace moves to another region |
Redeeming a handoff link is rate-limited to 20 attempts a minute from one address.
What each scope reads
Section titled “What each scope reads”There are two scopes. Configuration is how the workspace is set up, plus operational numbers. Full read adds what the Auditor role reads, minus reports and the data protection pages.
Configuration (both scopes)
Section titled “Configuration (both scopes)”| Area | What is read | What is never in it |
|---|---|---|
| Workspace | Workspace settings, reporting settings (the institution’s FIU details and thresholds), jurisdictions, the licence, the approval policy, the support access page and policy | Any report |
| People and access | People and their roles, the roles, teams and their members, escalation policies, API keys (names, prefixes, scopes, dates), single sign-on settings, SCIM (token names and dates), the WhatsApp connection status | A key, a token, a client secret |
| Detection | Rules and the rule catalogue, a rule’s definition, when a scheduled rule ran and whether it succeeded, rule packs, which lists exist | The values in a list |
| Screening | The list sources and their versions, screening settings, providers, re-screen runs (when, how many) | Provider credentials, matches |
| Integrations | Data sources, their mappings, file names with row counts and status, change-data-capture settings, webhooks, the status and timing of webhook deliveries | A webhook’s signing secret, a delivery’s payload, the row-by-row results of a file load |
| Operational figures | The summary counts, the Analytics figures (volume, typologies, rule performance, alert and decision outcomes), decision statistics and rule outcomes | Any customer or transaction |
Full read only
Section titled “Full read only”| Area | What is read |
|---|---|
| Work | The dashboard (it carries recent transactions), alerts, cases, suppressions |
| Customers and payments | Customers, transactions, real-time decisions, the values in lists |
| Screening | Potential matches |
| Models and backtests | Risk models, their schedule, backtests and their sampled hits |
| Oversight | The audit log, and change requests, without what they say about reports and data subject requests |
Never, whatever the scope
Section titled “Never, whatever the scope”| What | Why |
|---|---|
| Reports: an STR or CTR, the register, the downloads, even how many there are | Tipping-off |
| Exports and downloads: a data subject request’s export, a breach record’s export, the licence usage file | Data leaving the app |
| Data protection: data subject requests, legal holds, purge runs, breach records, the registers, retention and privacy settings | The institution’s own legal records. A data subject request says whether its customer is under investigation |
| A webhook delivery with its payload | Alert and case data as it was sent to the institution’s systems |
| What investigators wrote: comments, closure and escalation notes, an alert’s closing note | See the filter below |
| The AI assistant’s advice on an alert, its summary of a case and its draft of a report’s narrative, and a person’s batches of questions to it | Written about a customer’s alert, case or report; a narrative draft names the customer. A support session can’t start a batch, read one’s progress, or ask whether the assistant is available on the alert and case pages. Whether the assistant is on is readable as configuration; the key never is. Its tuning suggestions for a rule are different: they are about a rule and counts, hold no customer, and are readable with the configuration scope like the rule itself. A support session can never ask for them |
| Evidence files on a case and a report’s filing package | Never downloaded in a support session, whatever its scope. A full-read session sees that a file exists (its name, size and SHA-256); the note written about it and the reason it was removed are withheld |
| Personal notification settings, a person’s sign-in methods (recovery codes, passkeys), the single sign-on test, system health, the API description | For the workspace’s own people |
| Any change | Read-only |
A refused request answers 403 with "code": "support_session" and a reason:
reason |
Meaning |
|---|---|
write |
A support session is read-only: nothing can be changed, approved, created or sent from it. |
scope |
This support session covers the workspace’s configuration only; the workspace did not grant access to its data. |
route_not_allowed |
This is not available in a support session. |
audit_failed |
The read could not be recorded, so it was not served |
not_filterable |
The answer could not be passed through the filter, so it was not served |
ended |
The session ended between two steps of the same request |
The tipping-off filter
Section titled “The tipping-off filter”Telling anyone outside the institution that a suspicious transaction report was drafted, filed or exists is an offence in the jurisdictions SpeculaPro serves (FATF Recommendation 21). The provider’s staff are outside the institution. So a support session reads nothing that says so: not the reports themselves, and not what the rest of the workspace’s data says about them.
Every answer served to a support session, apart from catalogues and configuration that are the same whether or not a report exists, passes through a filter before it leaves:
| What | What the session reads |
|---|---|
| A case’s report linked timeline events | Left out, without a trace |
| Audit entries about reports and about data subject requests | Left out |
| Legal holds on a report, and change requests about a report or a data subject request | Left out |
| A case’s disposition | true_positive for both report filed and true positive, no report, including where a rule’s explanation quotes a disposition inside a sentence |
| Comments, closure notes, escalation notes and an alert’s closing note | [not shown in a support session], whatever they say. Showing some and withholding others would say which notes mention a report |
| Any field whose name speaks of a report or of the tipping-off flag | Dropped |
| Any list entry that carries one of the workspace’s report ids, report numbers or FIU references | Left out |
| An answer that is itself about a report | 404, as if nothing were there |
| An answer that isn’t JSON, or that can’t be parsed | Refused |
The filter runs for support sessions only. The workspace’s own people see everything their permissions allow, unchanged.
What is recorded
Section titled “What is recorded”Each event is written in the same transaction to the workspace’s audit log and to the provider’s own audit log. In the workspace’s log the actor is shown as SpeculaPro — <name> (acting from the console) or SpeculaPro support — <name> (inside a session).
| Action | When |
|---|---|
support.requested |
A member of staff asked; records the reason, the ticket reference, the scope and the minutes asked for |
support.approved, support.denied |
Someone in the workspace decided; records what was given |
support.cancelled |
The member of staff withdrew the request before a decision |
support.handoff_issued |
The console issued a one-time link |
support.session_started, support.session_ended |
A session was opened from a link, or signed out |
support.read |
One read made in a session. The workspace’s log keeps the full address read, up to 500 characters; the provider’s keeps the route only |
support.refused |
A request a session was refused: a write, a read outside its scope, or a route no session may read. The first refusal a minute for a session, route and reason is written at once; the ones that follow are counted and written as one entry, with the count, when the minute closes. A loop can’t flood either log |
support.revoked |
Someone in the workspace ended the access |
support.ended |
The provider gave the access back early |
support.expired |
A request lapsed, or an approval ran its time. Written by the worker within about a minute; the session itself is refused from the moment the time passes, whether or not the worker has run |
support.policy_changed |
The workspace’s policy changed; records before and after. Workspace log only |
A request the workspace’s policy refused outright is recorded on the provider’s side only
(support.request_refused): nobody in the workspace was asked.
The refusal log and the checks on scheduled deletion were added by migration
00057_provider_console_gaps; support access itself by 00055_support_access.
What a workspace should check
Section titled “What a workspace should check”- Who holds
support_access.manage. By default the Administrator and the MLRO. It is flagged as a security permission in the role editor. - The policy. Full read off unless there is a reason, and the longest access as short as your support cases need.
- That Security settings is under approval, so loosening the policy takes two people.
- The audit log after each access: filter on the actor SpeculaPro support and read what was opened.
Limits to know about
Section titled “Limits to know about”- The session sees what its scope allows for the whole workspace, not one case or one customer. There is no narrower scope than configuration.
- Full read shows customer names. Masking covers ID numbers, phone numbers, email addresses, dates of birth and full account numbers. Names, masked identifiers, amounts, dates and rule explanations are visible under full read. Weigh that before you allow it.
- The filter matches reports by their ids, numbers and FIU references, and by field names. Free text written by investigators is withheld entirely for that reason. Free text elsewhere (a customer’s name, a list’s description) is not rewritten.
- The newest 5,000 reports of a workspace feed the filter’s list of identifiers.
- Ending a session doesn’t end the approval. Until its time is up or the workspace revokes, the same member of staff can open another session.