Manage user consent and opt-out
Grant and revoke a user’s consent categories, set their opt-out preferences and read workspace consent and enforcement stats.
Prerequisites
Section titled “Prerequisites”- Enterprise installed (
enterprise.enabled: true). The routes are served in dev mode, so a license is not required. See Licensing & Features. - A Workspace with
spec.privacyset. This provisions the privacy-api. - The user’s pseudonymous id (
virtualUserId) if you call privacy-api directly. The service stores whatever key it receives, so a raw user id records state for a subject that matches no session or memory, and returns no error. - Access to the privacy-api Service from inside the cluster, and a ServiceAccount token it accepts.
If you build an application, call the dashboard’s workspace routes instead of privacy-api. They pseudonymise the user id for you and proxy to privacy-api with identical bodies. See Workspace routes for the paths and how they scope the user.
The steps below call privacy-api directly. Every route, body and response field is in the Privacy API reference.
Reach privacy-api
Section titled “Reach privacy-api”-
Forward the Service. It is named
privacy-<workspace>and lives in the workspace namespace.Terminal window kubectl port-forward -n <workspace-namespace> svc/privacy-<workspace> 8080:8080 -
Mint a token for a ServiceAccount in the workspace namespace, with the audience
omnia-session-api. The examples use$SA_TOKENandhttp://localhost:8080.Terminal window export SA_TOKEN=$(kubectl create token default -n <workspace-namespace> --audience omnia-session-api)
Grant or revoke consent
Section titled “Grant or revoke consent”Six consent categories exist. memory:identity, memory:location and memory:health need an explicit grant before memory writes in that category succeed. The other three need none. See Consent categories.
-
Grant categories. The service applies
grantsfirst, thenrevocations.Terminal window curl -sS -X PUT \http://localhost:8080/api/v1/privacy/preferences/<virtual-user-id>/consent \-H "Authorization: Bearer $SA_TOKEN" \-H "Content-Type: application/json" \-d '{"grants": ["memory:identity", "memory:location"]}'The response is the resulting state (illustrative values):
{"grants": ["memory:identity", "memory:location"],"defaults": ["memory:context", "memory:history", "memory:preferences"],"denied": ["memory:health"]} -
Revoke a category.
Terminal window curl -sS -X PUT \http://localhost:8080/api/v1/privacy/preferences/<virtual-user-id>/consent \-H "Authorization: Bearer $SA_TOKEN" \-H "Content-Type: application/json" \-d '{"revocations": ["memory:location"]}'privacy-api pushes the revocation to the workspace’s memory-api instances, which then apply the MemoryPolicy
consentRevocation.actionto memories already stored in that category. Each grant and revocation also writes a row to the privacy audit hub.
Set or remove an opt-out
Section titled “Set or remove an opt-out”Opt-out suppresses recording at a scope (all, workspace or agent) instead of per category.
-
Set an opt-out.
targetnames the workspace or agent, and is omitted forall.Terminal window curl -sS -X POST http://localhost:8080/api/v1/privacy/opt-out \-H "Authorization: Bearer $SA_TOKEN" \-H "Content-Type: application/json" \-d '{"virtualUserId": "<virtual-user-id>", "scope": "workspace", "target": "my-workspace"}'A successful call returns
204. -
Remove it by sending the same body with
DELETE.Terminal window curl -sS -X DELETE http://localhost:8080/api/v1/privacy/opt-out \-H "Authorization: Bearer $SA_TOKEN" \-H "Content-Type: application/json" \-d '{"virtualUserId": "<virtual-user-id>", "scope": "workspace", "target": "my-workspace"}'
Read stats
Section titled “Read stats”Both stats routes need the workspace query parameter. Enforcement stats filter on the Workspace UID, not its name.
-
Read the Workspace UID.
Terminal window export WS_UID=$(kubectl get workspace my-workspace -o jsonpath='{.metadata.uid}') -
Read the stats.
Terminal window curl -sS "http://localhost:8080/api/v1/privacy/enforcement-stats?workspace=$WS_UID" \-H "Authorization: Bearer $SA_TOKEN"curl -sS "http://localhost:8080/api/v1/privacy/consent/stats?workspace=$WS_UID" \-H "Authorization: Bearer $SA_TOKEN"The consent stats route requires the parameter but ignores its value.
Verify
Section titled “Verify”-
Read the user’s consent state. It returns the same
grants,defaultsanddeniedfields as the write.Terminal window curl -sS \http://localhost:8080/api/v1/privacy/preferences/<virtual-user-id>/consent \-H "Authorization: Bearer $SA_TOKEN" -
Read the user’s opt-outs. A
404means the user has no stored preferences.Terminal window curl -sS http://localhost:8080/api/v1/privacy/preferences/<virtual-user-id> \-H "Authorization: Bearer $SA_TOKEN" -
Confirm that opt-out is enforced in the workspace.
Terminal window kubectl get workspace my-workspace \-o jsonpath='{.status.conditions[?(@.type=="OptOutEnforced")]}'Truewith reasonPrivacyEnforcedmeans privacy-api is serving. See theOptOutEnforcedcondition for theFalsereasons.
Troubleshooting
Section titled “Troubleshooting”A consent write returns 400
Section titled “A consent write returns 400”The body names a category outside the six registered ones. The response reads unknown consent category: <value>. Use a value from Consent categories.
Sessions show [OPTED_OUT] content or memories stop appearing
Section titled “Sessions show [OPTED_OUT] content or memories stop appearing”If the user has opted out, the sentinel and the missing memories are expected. If they have not, privacy-api may be unavailable: while spec.privacy is set and privacy-api cannot be resolved, session-api and memory-api treat every subject as opted out. Check the OptOutEnforced condition. PrivacyUnavailable means privacy-api is not serving yet. The services re-resolve it periodically and recover without a restart.
To alert on an outage, watch omnia_session_api_content_suppressed_total{reason="privacy-unavailable"}. The user-opted-out series is ordinary traffic. See Behaviour when privacy-api cannot answer.
The service logs PRIVACY NOT ENFORCED
Section titled “The service logs PRIVACY NOT ENFORCED”The Workspace has no spec.privacy, so opt-out is off and all writes are recorded. Set spec.privacy and confirm the Workspace reports status.privacyURL.