According to the Switch edu-ID architecture, there are three sources for attributes of a user:
The shared attribute service described here is a complementary attribute source. It allows basically arbitrary services or applications (a client) to set specific attribute values for users. These attributes can then be made available to selected services.
Typical applications are:
Prerequisites:
Current limitations:
The shared attribute API uses a subset of the SCIM specification to set and reset group memberships.
Roles:
Authentication and permissions:
Basic Authentication. An API-user is set up by the Switch edu-ID team on request.
The permissions of an API-user can be adjusted finely. Depending on the requirements, the following permissions can be granted to an API-user: GET-Users, POST-Users, PATCH-Groups, GET-Groups, POST-Groups.
Attributes supported in the profile:
Basic steps to set and reset group memberships for a user:
The required group(s) will be created for the client by the Switch edu-ID team.
API endpoints:
In the examples below, the REST service endpoint base url is https://eduid.ch/sg/index.php/.
Before a user can be associated to groups, an internal user record has to be created. The record contains the internal identifier "id", which is used to add or remove a user in a group.
POST /sg/index.php/Users
The body must contain information about the new user in JSON format as shown in the following example:
{
"externalID":"1234567@eduid.ch"
}
Results:
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"id":"2819c223-7f76-453a-919d-413861904646",
"externalID":"1234567@eduid.ch",
"meta": {
"created":"2016-07-24T11:29:51Z",
"modified":"2016-07-24T11:51:09Z"
},
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"]
}
Notes:
To add an existing user (with the internal "id" 2819c22...) to an existing group (acbf3ae...):
PATCH /Groups/acbf3ae7-8463-425b-bded-9b4da3f908ce
Content-Type: application/scim+json
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations":[
{
"op":"add",
"path":"members",
"value":[
{
"$ref": "https://eduid.ch/sg/index.php/Users/2819c223...413861904646",
"value": "2819c223-7f76-453a-919d-413861904646"
}
]
}
]
}
Response: (if successful)
HTTP/1.1 204 No Content Location: "https://eduid.ch/sg/index.php/Groups/acbf3ae7-8463-...-9b4da3f908ce"
To remove the member (with the internal "id" 2819c22...) from the group (acbf3ae...) use a PATCH operation with a path expression:
PATCH /sg/index.php/Groups/acbf3ae7-8463-425b-bded-9b4da3f908ce
Accept: application/scim+json
Content-Type: application/scim+json
{
"Schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations":[{
"op":"remove",
"path":"members[value eq \"2819c223-7f76-...413861904646\"]"
}]
}
Response:
Find all users in an existing group (acbf3ae...):
GET /Groups/acbf3ae7-8463-425b-bded-9b4da3f908ce
Example response: (if successful)
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"id":"acbf3ae7-8463-425b-bded-9b4da3f908ce",
"displayName":"Test Group",
"schemas":["urn:ietf:params:scim:schemas:core:2.0:Group"],
"members":[
{"value":"2819c223-7f76-453a-919d-413861904646", "display":" "},
{"value":"c626d45b-2bbd-483d-8d34-9c1c6dc5fdc3", "display":" "}
]
}
Note: To use this function, the API user needs to have the permission "GET-groups".
Request:
GET /sg/index.php/Users?filter=externalID eq “1234567@eduid.ch” Host: eduid.ch Accept: application/scim+json
Example response:
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"schemas":["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults":1,
"Resources":[
{
"id":"e64a2bef-02f2-4a67-8f29-6121a8f4aff3",
}
]
}
and check his/her group membership:
GET /sg/index.php/Users/e64a2bef-02f2-4a67-8f29-6121a8f4aff3
Example response:
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"id":"e64a2bef-02f2-4a67-8f29-6121a8f4aff3",
"externalID":"1234567@eduid.ch",
"groups": [
{
"value":"acbf3ae7-8463-425b-bded-9b4da3f908ce",
"display":"Test Group"
}
],
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"]
}
This user is a member of the group “National Library License Compliant”
Error responses that can be issued for all of the above GET, POST and PATCH requests:
Response:
HTTP/1.1 401 Unauthorized Content-Type: application/scim+json
The authentication was ok, but the client is not authorized to do this operation.
Response:
HTTP/1.1 403 Forbidden Content-Type: application/scim+json
If the referenced user or group does not exist.
Response:
HTTP/1.1 404 Not Found Content-Type: application/scim+json
https://test.eduid.ch/sg/index.php/1234567@eduid.chf4d40595-6d7d-41bc-9fa2-7139d2fcf892curl --user apiuser:passwd -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{ "externalID":"1234567@eduid.ch" }' https://test.eduid.ch/sg/index.php/Users
Response:
{"externalID":"1234567@eduid.ch","schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"id":"6943fc0d-61a5-4dc8-a7fa-234243323a49"}
curl --user apiuser:passwd https://test.eduid.ch/sg/index.php/Users/6943fc0d-61a5-4dc8-a7fa-234243323a49
Response:
{"id":"6943fc0d-61a5-4dc8-a7fa-234243323a49","externalID":"1234567@eduid.ch","schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"groups":[]}
(here, the user belongs to no group)
add the user 6943fc0d-61a5-4dc8-a7fa-234243323a49 to the group f4d40595-6d7d-41bc-9fa2-7139d2fcf892 :
Precondition: the user and the group must already exist
curl --user apiuser:passwd -X PATCH \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations":[
{
"op":"add",
"path":"members",
"value":[
{
"$ref": "https://test.eduid.ch/sg/index.php/Users/6943fc0d-61a5-4dc8-a7fa-234243323a49",
"value": "6943fc0d-61a5-4dc8-a7fa-234243323a49"
}
]
}
]
}' https://test.eduid.ch/sg/index.php/Groups/f4d40595-6d7d-41bc-9fa2-7139d2fcf892
Response:
HTTP/1.1 200 OK
curl --user apiuser:passwd https://test.eduid.ch/sg/index.php/Users/6943fc0d-61a5-4dc8-a7fa-234243323a49
Response:
{"id":"6943fc0d-61a5-4dc8-a7fa-234243323a49","externalID":"1234567@eduid.ch","schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"groups":[{"value":"f4d40595-6d7d-41bc-9fa2-7139d2fcf892","display":"National Licenses Programme"}]}
The groups object is not empty now.
Remove the user 6943fc0d-61a5-4dc8-a7fa-234243323a49 from the group f4d40595-6d7d-41bc-9fa2-7139d2fcf892 :
curl --user apiuser:passwd -X PATCH \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data '{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations":[
{
"op":"remove",
"path":"members[value eq \"6943fc0d-61a5-4dc8-a7fa-234243323a49\"]"
}
]
}' https://test.eduid.ch/sg/index.php/Groups/f4d40595-6d7d-41bc-9fa2-7139d2fcf892
Response:
HTTP/1.1 200 OK
The above requests can also be made using the human-friendly web GUI that is available here:
GUI endpoints:
To access the GUI, client credentials are required.
In the national licenses case a registration service decides for each user if he/she is entitled to have access to contents of publishers who participate in the programme. For each user who has access, the shared property “national-license-compliant” is written to a shared database. The Swiss edu-ID IdP reads the shared database and sets the attribute “common-lib-terms” for the users who are entitled to have access to the contents.

In this use case, Switch edu-ID acts as a SCIM service and the national license registration platform as SCIM client.
Available SCIM API endpoints:
POST /UsersGET /Users/{id}GET /Users?filterPATCH /GroupsPOST /Groups (not for public use)PUT /Groups (not for public use)DELETE /Groups (not for public use)Cantonal libraries are legally mandated to provide access to digital publications to their patrons. These are typically private persons who meet particular conditions like

Requirements:
Solution concept: