Overview
Set permissions on each document when you index it. Search only returns documents the signed-in user is allowed to see.
User context uses login email. The person searching is always an amberSearch user identified by the email on their account (the email they have when they log in to amber). Every permission that targets a specific person must use that same email: POST /users → user.email, allowed_users → { "email": "..." }, POST /memberships → member_email, and POST .../documents/check-access → user_email. Email lookups are case-insensitive (stored lowercased).
Pick one primary rule per document:
| Goal | Set |
|---|
| Everyone in your amberSearch org can find it | allow_anonymous_access: true, or omit permissions entirely |
| Only listed people | allowed_users (after indexing those users --- see below) |
| Members of named groups | allowed_groups (after creating groups and memberships --- see below) |
Documents indexed without a permissions block are stored with the anonymous token and are visible to every signed-in user in your amberSearch org. If you want a document to be restricted, you must send allowed_users and/or allowed_groups on it.
1. Open to the whole organization
"permissions": {
"allow_anonymous_access": true
}
2. Specific users only
Permissions are always resolved by email --- the same address on the user’s amberSearch account.
a) Register each person once per datasource. email is required and must equal the address on their amberSearch user profile (same as when they log in). The optional name is for display only and does not replace email for access checks.
curl -X POST "https://customerDomain.ambersearch.de/api/indexing/users" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datasource": "internal_wiki",
"user": {
"email": "[email protected]",
"name": "Alice Smith"
}
}'
Response codes for POST /users
| Code | When |
|---|
| 200 OK | User created. |
| 400 Bad Request | user.email is missing or empty after normalization (trim + lower-case). |
| 404 Not Found | Datasource not found. |
| 409 Conflict | A user with the same (normalized) email already exists in this datasource. |
Update a user’s display name later with PUT /users/{datasource}/{email}:
curl -X PUT "https://customerDomain.ambersearch.de/api/indexing/users/internal_wiki/[email protected]" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Alice S." }'
Response codes for PUT /users/{datasource}/{email}
| Code | When |
|---|
| 200 OK | User updated. |
| 400 Bad Request | The email path parameter is empty after normalization. |
| 404 Not Found | Datasource not found, or no user with that email in the datasource. |
b) Reference them on the document with allowed_users and the same emails:
3. Groups
Order of operations:
- Users ---
POST /users for each person (same as above).
- Group ---
POST /groups with a name. Group name rules: must be non-empty, must not contain whitespace, and must not start with amber (case-insensitive).
- Membership ---
POST /memberships with group_name and either member_email (the member’s amber login email) or member_group_name (to nest another group). Exactly one of the two must be set.
- Document ---
allowed_groups: ["engineering"].
Create a group:
curl -X POST "https://customerDomain.ambersearch.de/api/indexing/groups" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datasource": "internal_wiki",
"group": { "name": "engineering" }
}'
Response codes for POST /groups
| Code | When |
|---|
| 200 OK | Group created. |
| 400 Bad Request | group.name contains whitespace or starts with amber (case-insensitive). |
| 404 Not Found | Datasource not found. |
| 409 Conflict | A group with that name already exists in this datasource. |
Rename it later with PUT /groups/{datasource}/{group_name}:
curl -X PUT "https://customerDomain.ambersearch.de/api/indexing/groups/internal_wiki/engineering" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "group_name": "eng-team" }'
Response codes for PUT /groups/{datasource}/{group_name}
| Code | When |
|---|
| 200 OK | Group renamed. |
| 400 Bad Request | The new group_name contains whitespace or starts with amber. |
| 404 Not Found | Datasource not found, or no group with that name in the datasource. |
Add a user as a member (member_email = amber login email):
curl -X POST "https://customerDomain.ambersearch.de/api/indexing/memberships" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datasource": "internal_wiki",
"membership": {
"group_name": "engineering",
"member_email": "[email protected]"
}
}'
Or nest one group inside another (member_group_name):
curl -X POST "https://customerDomain.ambersearch.de/api/indexing/memberships" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datasource": "internal_wiki",
"membership": {
"group_name": "all-staff",
"member_group_name": "engineering"
}
}'
Response codes for POST /memberships
| Code | When |
|---|
| 200 OK | Membership created. |
| 404 Not Found | Datasource not found, parent group not found, or the referenced user / member_group_name does not exist. |
| 409 Conflict | The membership already exists, or the new group → group edge would close a cycle — the response message lists the offending path. |
Document snippet:
"permissions": {
"allowed_groups": ["engineering"]
}
Remove a membership
DELETE /memberships/{datasource}/{group_name}/{member_type}/{member_id} --- member_type is user or group. For user, member_id is the email; for group, it is the nested group’s name.
curl -X DELETE "https://customerDomain.ambersearch.de/api/indexing/memberships/internal_wiki/engineering/user/[email protected]" \
-H "Authorization: Bearer YOUR_API_KEY"
curl -X DELETE "https://customerDomain.ambersearch.de/api/indexing/memberships/internal_wiki/all-staff/group/engineering" \
-H "Authorization: Bearer YOUR_API_KEY"
Response codes for DELETE /memberships/{datasource}/{group_name}/{member_type}/{member_id}
| Code | When |
|---|
| 200 OK | Membership removed. |
| 400 Bad Request | member_type is neither user nor group. |
| 404 Not Found | Datasource, parent group, referenced user / member-group, or the membership row itself was not found. |
Group membership is transitive. When engineering is a member of all-staff, anyone who is a member of engineering (directly or via further nesting) is also treated as a member of all-staff for access checks.
Verify access
user_email must be the same amber login email you use in /users and permissions. The check resolves the user’s transitive group memberships and compares them to the document’s stored access tokens.
curl -X POST "https://customerDomain.ambersearch.de/api/indexing/documents/check-access" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"datasource": "internal_wiki",
"document_id": "architecture-doc",
"user_email": "[email protected]"
}'
{
"has_access": true,
"datasource": "internal_wiki",
"document_id": "architecture-doc",
"user_email": "[email protected]"
}
Response codes for POST /documents/check-access
| Code | When |
|---|
| 200 OK | Access decision returned in has_access. |
| 404 Not Found | Datasource not found, or Solr has no document with that id. |
| 422 Unprocessable Entity | user_email is missing or empty (rejected by the request model). |
Remember that newly indexed documents may take up to 2 hours to be committed and become discoverable; check-access queries the search index directly so it will not find a document that is still being processed.
Behaviour notes
- Permission updates can take a short time to apply everywhere in search.
- Tighten rules after testing: start with
allow_anonymous_access: true (or no permissions) if you need to confirm indexing before locking down.
- Renaming a group after documents reference it will leave existing Solr documents pointing at the old name; re-index those documents to apply the new name.