Service Authorization for Data Spaces

Living Document,

Previous Versions:
Issue Tracking:
GitHub
Inline In Spec
Editor:
(Ghent University - imec)

Abstract

This is a specification for adding authorization on services with UMA. This spec defines an authorization abstraction layer over streams and non-HTTP based protocols.

1. Introduction

Modern distributed systems increasingly rely on continuous or session-based service interactions—spanning data streams, message brokers, IoT telemetry, or custom transport protocols. Traditional authorization frameworks like OAuth 2.0 and UMA 2.0 primarily target discrete, HTTP-based request/response exchanges. The Service Authorization for Data Spaces (SA4DS) extends A4DS with a simple mechanism for maintaining (continuous) access authorization to non-HTTP services, including streaming resources, while preserving UMA’s policy-driven and decentralized properties. Throughout this document, “stream” is used as a shorthand for these long-lived service interactions. SA4DS does not require clients to understand or request fine-grained authorization semantics; such semantics are optional and Resource Server–defined.

This document defines:

2. Terminology

This specification reuses terms from [oauth20], [uma-fed], [uma-grant], and [a4ds].

This specification also relies on JSON [json], JWT [jwt], bearer token usage [bearer], OAuth token introspection [introspection], HTTP Link headers [link-header], HTTP semantics [http-semantics], HTTP caching [http-caching], well-known URIs [wk-uri], Server-Sent Events [eventsource], WebSockets [websockets], TLS [tls], mutual-TLS OAuth client authentication and certificate-bound access tokens [mtls], and DPoP [dpop] where those mechanisms are used by a deployment.

Additional terms:

3. Service Token Endpoint

The Service Token Endpoint enables a client to exchange a valid UMA Requesting Party Token (RPT) for a short-lived Service Token representing the permissions granted by the RPT for Service Resources hosted by the Resource Server (RS). The Service Token Endpoint is hosted by the RS.

3.1. Endpoint and method

The Service Token Endpoint:

3.2. Request

The Service Token Endpoint has two request modes:

For an initial Service Token request, the client MUST send:

The request body for an initial Service Token request MAY be omitted. If present, the request body MAY be an empty JSON object. The client does not send resource_url, resource_scopes, or access_description to the Service Token Endpoint. The RS MUST derive the Service Resource permissions represented by the Service Token from the validated RPT. It MUST include only permissions for Service Resources hosted by that RS.

For an authorization session update or refresh request, the client MUST send:

The RS MUST validate that the RPT is valid before issuing a Service Token. The validation mechanism is deployment-specific and can include introspection with the AS. For authorization session update or refresh requests, the RS MUST validate that the Authorization Session Token authenticates the authorization session being updated or refreshed.

The RS MUST verify that the presented RPT authorizes the full permission set needed for the service session. A Service Token issued for an existing authorization session MUST represent the complete currently authorized permission set for that session; its permissions replace, rather than merely supplement, the permissions represented by the previous Service Token.

3.3. Response

On success, the RS MUST return 200 OK with a JSON response body containing:

The client uses service_token as a bearer or proof-of-possession credential when initiating the service channel. To maintain continuous access, the client MUST refresh the Service Token before it expires by obtaining or reusing a valid RPT and calling the Service Token Endpoint again with the Authorization Session Token in the request body.

A successful authorization session update or refresh at the Service Token Endpoint proves to the RS that the client remains authorized for the service session. This specification does not require the client to re-authorize on an existing Service Resource connection after that endpoint call.

When accepting a Service Token on a Service Resource connection, the RS MUST associate that connection with the corresponding authorization session. After a successful update or refresh, the RS MUST apply the refreshed authorization state to Service Resource connections associated with that session. The client does not need to present the newly issued Service Token again on those existing connections.

The RS MAY rotate the Authorization Session Token by returning a new authorization_session_token member in any successful Service Token response. When a response contains an authorization_session_token for an existing session, the client MUST use the new token for future requests authenticated to that authorization session. The RS SHOULD allow a short overlap window during which the previous Authorization Session Token remains valid for in-flight requests.

The RS MUST include Cache-Control: no-store in successful responses containing Service Tokens or Authorization Session Tokens. Clients and intermediaries MUST NOT store these responses.

3.4. Errors

If a required request body is missing, is not valid JSON, or does not contain the required members, the RS MUST respond with 400 Bad Request. If the request body is omitted for an initial Service Token request, the omission is not an error.

If no valid RPT is provided for an initial, update, or refresh Service Token request, the RS MUST respond with 401 Unauthorized. If the RS has sufficient context to identify permissions that the client needs, the response SHOULD include an UMA WWW-Authenticate header containing a permission ticket (e.g., with an as_uri and ticket).

If the RPT in an update or refresh request does not authorize the full permission set needed for the service session, the RS MUST respond with 401 Unauthorized and an UMA WWW-Authenticate header containing a permission ticket for the required permissions.

If the Authorization Session Token is missing, invalid, expired, or does not authenticate the authorization session being updated, the RS MUST respond with 401 Unauthorized.

4. Authorization Event Stream

The Authorization Event Stream enables the RS to notify a client that the authorization state of a session has changed, without embedding authorization control messages in the Service Resource data channel. This allows the same authorization update mechanism to be used with WebSockets, SSE, databases, message brokers, custom sockets, and other service transports.

The Authorization Event Stream is hosted by the RS. The RS MUST NOT send Service Resource data over the Authorization Event Stream.

4.1. Event stream connection

The Authorization Event Stream endpoint:

The authorization_events URL is an RS-defined absolute URL for an authorization session. Clients MUST treat the URL as opaque and MUST NOT construct authorization event stream URLs from an Authorization Session ID.

If the Authorization Session Token is missing, invalid, expired, or does not authenticate the authorization session associated with the event stream URL, the RS MUST respond with 401 Unauthorized.

The client MAY connect to the Authorization Event Stream after receiving a Service Token response containing an authorization_events URL and an Authorization Session Token. Refreshing a Service Token does not require the client to reconnect the Authorization Event Stream unless the RS closes the stream or rejects the current Authorization Session Token.

4.2. Authorization events

Each authorization event MUST contain an SSE event field identifying the authorization event type and an SSE data field containing a UTF-8 JSON object. The RS SHOULD include an SSE id field on each authorization event. Event IDs MUST be unique within an authorization session and MUST be ordered according to the order in which the RS generated the events for that session. If the client reconnects with a Last-Event-ID value, the RS SHOULD replay authorization events generated after that event ID when replay is still available. If replay is not available, the RS SHOULD require the client to refresh the Service Token or reconnect the service session.

When the RS rotates an Authorization Session Token, it SHOULD continue accepting the previous Authorization Session Token for the overlap window described in § 3.3 Response on the Authorization Event Stream and Service Token Endpoint. After the overlap window ends, the RS MAY close event streams authenticated with the previous Authorization Session Token or require the client to reconnect using the new token.

Each event object MAY contain:

This specification defines the following event types:

When receiving authorization_required, the client SHOULD use the provided UMA permission ticket to obtain a fresh RPT from the AS, then call the Service Token Endpoint with the fresh RPT and the Authorization Session Token.

When receiving token_refresh_required, the client SHOULD call the Service Token Endpoint before the current Service Token expires, using either an existing valid RPT that authorizes the full permission set needed for the service session or a fresh RPT obtained from the AS using the provided permission ticket. The RS includes the ticket so that the client can obtain a fresh RPT immediately, but the client MAY ignore the ticket when it already has a suitable RPT. After sending token_refresh_required, the RS MAY continue sending Service Resource data for a grace period, withhold Service Resource data until the client refreshes, or terminate the service connection immediately, according to local policy and transport constraints.

When receiving session_terminated, the client MUST stop using Service Tokens for that session. The RS MUST stop sending Service Resource data and reject further service operations for that session. The RS MUST also terminate, or otherwise make unusable, all Service Resource connections associated with that session.

5. Discovery

The RS MUST make the Service Token Endpoint discoverable:

The RS MUST make an Authorization Event Stream URL discoverable only by returning an authorization_events member in a successful Service Token response. The returned URL is specific to the authorization session.

When the Service Resource is HTTP-based and the client does not present a valid Service Token, the RS SHOULD combine authorization challenge and endpoint discovery in the same 401 Unauthorized response. The response SHOULD include an UMA WWW-Authenticate header containing a permission ticket for the requested Service Resource and scopes, and a Link header identifying the Service Token Endpoint.

/.well-known/sa4ds-configuration is not yet registered.

Non-normative discovery examples are provided in flow examples.

6. Flow (Non-normative)

PlantUML Diagram

The numbered actions in the diagram correspond to the following steps:

  1. Client → RS: The client discovers a protected Service Resource (e.g., by attempting to access it, or by out-of-band discovery depending on the transport).

  2. RS → Client: If no valid token is presented, the RS returns 401 Unauthorized with an UMA permission ticket and discovery information (e.g., the Authorization Server as_uri and the Service Token Endpoint).

  3. Client → AS: The client obtains or refreshes an RPT from the AS using the UMA ticket (UMA details are out of scope for this specification).

  4. Client → Service Token Endpoint: The client requests a Service Token by presenting the RPT. The RS introspects the RPT at the AS, derives the Service Resource permissions granted by it, creates an authorization session, and returns a short-lived service_token, an authorization_session_id, an authorization_session_token, and optionally an authorization_events URL.

  5. Client ↔ RS: The client may connect to the Authorization Event Stream URL using the Authorization Session Token.

  6. Client ↔ Service Resource: The client starts (or maintains) the service channel, presenting the service_token using transport-specific mechanisms.

  7. Client ↔ RS/AS/Service Token Endpoint: If a later service operation requires additional authorization, the RS sends authorization_required on the Authorization Event Stream with a permission ticket. The client obtains a fresh RPT from the AS using that ticket, then calls the Service Token Endpoint with the fresh RPT and the Authorization Session Token. If authorized, the RS returns an updated Service Token representing the complete permission set for the same authorization session and MAY rotate the Authorization Session Token.

  8. RS ↔ AS/Client/Service Token Endpoint: The RS enforces continuous authorization through expiry, validation, and revocation. If renewal is needed and the Authorization Event Stream is active for the affected session, the RS sends token_refresh_required with a permission ticket so the client can obtain an RPT if needed and call the Service Token Endpoint. A client can also refresh without the Authorization Event Stream by refreshing the Service Token before the expires_in lifetime elapses. If authorization fails and cannot be refreshed, the RS terminates the service channel.

The following examples illustrate a complete flow from discovery to starting a service channel, extending the session with an additional scope, and refreshing its authorization.

1. Discovery: Accessing the Service Resource (HTTP-based)

GET /service_1 HTTP/1.1
Host: rs.example.org

2. Get ticket: RS challenges the client with an UMA permission ticket (+ endpoint discovery)

HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA as_uri="https://as.example.org", ticket="eyJhbGciOi..."
Link: <https://rs.example.org/service/tokens>; rel="https://spec.knows.idlab.ugent.be/service-authorization-for-data-spaces/service-token-endpoint"

2a. Discovery (alternative): Discovering the Service Token Endpoint via well-known configuration

GET /.well-known/sa4ds-configuration HTTP/1.1
Host: rs.example.org
HTTP/1.1 200 OK
Content-Type: application/json

{
  "service_token_endpoint": "https://rs.example.org/service/tokens"
}

3. RPT: Obtaining an RPT from the AS for connection-level access (UMA flow; details depend on UMA deployment)

POST /token HTTP/1.1
Host: as.example.org
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket&ticket=eyJhbGciOi...
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "access_token": "eyJhbGciOi...<RPT>...",
  "token_type": "Bearer",
  "expires_in": 3600
}

4. Service Token: Exchanging an RPT for a connection-level Service Token

POST /service/tokens HTTP/1.1
Host: rs.example.org
Authorization: Bearer eyJhbGciOi...<RPT>...
Content-Type: application/json

{}
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "service_token": "eyJhbGciOi...<service-token>...",
  "service_token_format": "jwt",
  "expires_in": 60,
  "authorization_session_id": "a91e45a2-...",
  "authorization_session_token": "eyJhbGciOi...<authorization-session-token>...",
  "authorization_events": "https://rs.example.org/service/authorization-events/evt-f5d2"
}

5. Authorization events: Connecting to the Authorization Event Stream

GET /service/authorization-events/evt-f5d2 HTTP/1.1
Host: rs.example.org
Accept: text/event-stream
Authorization: Bearer eyJhbGciOi...<authorization-session-token>...
HTTP/1.1 200 OK
Content-Type: text/event-stream

6. Start service channel: Starting a service channel using the Service Token (WebSocket handshake)

GET /service_1/ws HTTP/1.1
Host: rs.example.org
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Authorization: Bearer eyJhbGciOi...<service-token>...
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

7. Service operation: Requesting an operation that requires an additional scope

The client sends the following transport-specific message over the established service channel:

{
  "action": "subscribe",
  "event": "orders"
}

7a. Additional scope required: RS sends an authorization event when the operation requires more authorization

event: authorization_required
id: evt-7b31
data: {"authorization_session_id":"a91e45a2-...","ticket":"eyJhbGciOi..."}

7b. RPT: Obtaining a fresh RPT using the ticket from the authorization_required event

POST /token HTTP/1.1
Host: as.example.org
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket&ticket=eyJhbGciOi...
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "access_token": "eyJhbGciOi...<fresh_RPT>...",
  "token_type": "Bearer",
  "expires_in": 3600
}

7c. Service Token (update): Exchanging a fresh RPT for an updated Service Token

POST /service/tokens HTTP/1.1
Host: rs.example.org
Authorization: Bearer eyJhbGciOi...<fresh_RPT>...
Content-Type: application/json

{
  "authorization_session_token": "eyJhbGciOi...<authorization-session-token>..."
}
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "service_token": "eyJhbGciOi...<updated-service-token>...",
  "service_token_format": "jwt",
  "expires_in": 60,
  "authorization_session_id": "a91e45a2-...",
  "authorization_session_token": "eyJhbGciOi...<rotated-authorization-session-token>...",
  "authorization_events": "https://rs.example.org/service/authorization-events/evt-f5d2"
}

After receiving the updated Service Token, the client continues the service channel. A transport profile can define when the client needs to present the updated Service Token on an existing channel or re-establish the channel.

8a. Enforcement: RS determines that the authorization associated with the session is no longer active

POST /introspect HTTP/1.1
Host: as.example.org
Authorization: Basic <rs-credentials>
Content-Type: application/x-www-form-urlencoded

token=eyJhbGciOi...<RPT>...
HTTP/1.1 200 OK
Content-Type: application/json

{
  "active": false
}

If introspection returns active: true, the RS continues the session without sending a refresh event.

8b. Token refresh required: RS signals that the session needs a refreshed Service Token

event: token_refresh_required
id: evt-8c42
data: {"authorization_session_id":"a91e45a2-...","ticket":"eyJhbGciOi...","expires_in":10}

8c. RPT: Obtaining a fresh RPT using the ticket from the token_refresh_required event

POST /token HTTP/1.1
Host: as.example.org
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Auma-ticket&ticket=eyJhbGciOi...
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "access_token": "eyJhbGciOi...<refreshed_RPT>...",
  "token_type": "Bearer",
  "expires_in": 3600
}

8d. Service Token (refresh): Refreshing the session after token_refresh_required

POST /service/tokens HTTP/1.1
Host: rs.example.org
Authorization: Bearer eyJhbGciOi...<refreshed_RPT>...
Content-Type: application/json

{
  "authorization_session_token": "eyJhbGciOi...<rotated-authorization-session-token>..."
}
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "service_token": "eyJhbGciOi...<refreshed-service-token>...",
  "service_token_format": "jwt",
  "expires_in": 60,
  "authorization_session_id": "a91e45a2-...",
  "authorization_session_token": "eyJhbGciOi...<new-authorization-session-token>...",
  "authorization_events": "https://rs.example.org/service/authorization-events/evt-f5d2"
}

7. Token Validation and Lifetimes

The RS MUST validate the RPT before issuing a Service Token. The validation mechanism is deployment-specific and can include OAuth token introspection with the AS. When the service_token_format identifies a JWT-based Service Token, the RS MUST embed an exp claim and a unique jti in each Service Token.

A Service Token’s expiration time MUST NOT be later than the earliest explicit expiration time of the presented RPT or of any authorization state on which the Service Token depends. The RS MUST shorten the Service Token lifetime when necessary to satisfy this requirement.

The RS MAY introspect authorization state during a session or process revocation notifications from the AS. If the RS determines that the current Service Token must be refreshed and an Authorization Event Stream is active for the affected session, the RS MAY send a token_refresh_required event before rejecting further service operations. The RS MAY also reject further service operations immediately.

Clients MUST NOT rely on the Authorization Event Stream as the only refresh trigger. A client can refresh without using the Authorization Event Stream by obtaining or reusing a valid RPT and calling the Service Token Endpoint with the RPT in the Authorization header and the Authorization Session Token in the request body before the current Service Token expires.

The RS MUST terminate the service connection when:

8. Security Considerations

All communications MUST occur over TLS. Tokens SHOULD be proof-of-possession (mTLS or DPoP) bound when the selected transport can carry the required proof. Service Tokens MUST be short-lived, satisfy the expiration bound in § 7 Token Validation and Lifetimes, and be audience-restricted only to the RS.

Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

References

Normative References

[A4DS]
Knowledge on Web Scale Group, IDLab, Ghent University - imec. Authorization for Data Spaces. n.d.. URL: https://spec.knows.idlab.ugent.be/A4DS/L1/latest/
[BEARER]
M. Jones; D. Hardt. The OAuth 2.0 Authorization Framework: Bearer Token Usage. October 2012. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc6750/
[DPOP]
D. Fett; et al. OAuth 2.0 Demonstrating Proof of Possession (DPoP). September 2023. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc9449/
[EVENTSOURCE]
Ian Hickson. Server-sent events. Living Standard. URL: https://html.spec.whatwg.org/multipage/server-sent-events.html
[HTTP-CACHING]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Caching. June 2022. Internet Standard. URL: https://httpwg.org/specs/rfc9111.html
[HTTP-SEMANTICS]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Semantics. June 2022. Internet Standard. URL: https://httpwg.org/specs/rfc9110.html
[INTROSPECTION]
J. Richer, Ed.. OAuth 2.0 Token Introspection. October 2015. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc7662/
[JSON]
T. Bray, Ed.. The JavaScript Object Notation (JSON) Data Interchange Format. December 2017. Internet Standard. URL: https://www.rfc-editor.org/info/rfc8259/
[JWT]
M. Jones; J. Bradley; N. Sakimura. JSON Web Token (JWT). May 2015. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc7519/
M. Nottingham. Web Linking. October 2017. Proposed Standard. URL: https://httpwg.org/specs/rfc8288.html
[MTLS]
B. Campbell; et al. OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens. February 2020. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc8705/
[OAUTH20]
D. Hardt, Ed.. The OAuth 2.0 Authorization Framework. October 2012. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc6749/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[TLS]
E. Rescorla. The Transport Layer Security (TLS) Protocol Version 1.3. July 2026. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc9846/
[UMA-FED]
Maciej Machulak; Justin Richer; Eve Maler, Ed.. Federated Authorization for User-Managed Access (UMA) 2.0. 7 January 2018. Recommendation. URL: https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-federated-authz-2.0.html
[UMA-GRANT]
Maciej Machulak; Justin Richer; Eve Maler, Ed.. User-Managed Access (UMA) 2.0 Grant for OAuth 2.0 Authorization. 7 January 2018. Recommendation. URL: https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-grant-2.0.html
[WEBSOCKETS]
I. Fette; A. Melnikov. The WebSocket Protocol. December 2011. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc6455/
[WK-URI]
M. Nottingham. Well-Known Uniform Resource Identifiers (URIs). May 2019. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc8615/

Issues Index

/.well-known/sa4ds-configuration is not yet registered.