Stream API

Authentication

Most of the API calls that Stream uses require you to be authenticated to the API. The first authentication can either be done through the use of an X509 certificate or using credentials of a local account, but every single API call afterwards will need to bear the authentication information nonetheless. Regardless of the chosen authentication method, the authorization used must have sufficient permissions to perform the desired operation.

NOTE: Stream can be configured to only allow X509 Authentication (stream.security.authentication.enforce-x509)

Authenticating using API-ID and API-KEY

This method of authentication requires you to send your Stream local account credentials as HTTP headers:

HTTP Header Description
X-API-ID The local identity identifier
X-API-KEY The local identity password
X-API-IDPROV Optional. The name of the identity provider to authenticate against. Defaults to the enabled local provider

To check whether the credentials are correct, you can perform a GET request on /api/v1/security/principals/self and check for the response status:

 $ curl https://stream.example.com/api/v1/security/principals/self -H "X-API-ID: <identifier>" -H "X-API-KEY: <password>" -H "Accept: application/json"

Possible responses are:

HTTP Response code Additional information
200 The login information were correct
400 The identity provider given in X-API-IDPROV does not exist or is disabled (SEC-AUTH-007)
401 Authentication error, please refer to the response body for more details

Authenticating using an X509 certificate

This method of authentication requires to have an X509 certificate that has the clientAuth EKU and a Stream X509 account with this certificate's Distinguished Name as identifier. RSA keys must be at least 2048 bits long. It also requires you to have imported the CA that issued this certificate in Stream and turning on the "Trusted for client authentication" switch on that CA.

Stream does not terminate TLS itself: the client certificate must be validated by the reverse proxy in front of Stream, which then forwards it in an HTTP header. The name of that header is set with the stream.security.http.headers.certificate configuration key, and X509 authentication is disabled while it is not set. The header value can be a base64 encoded DER certificate (HAProxy), a URL encoded PEM certificate (Nginx) or the Traefik forwarded certificate format.

You must then present the certificate to the reverse proxy on the request you are performing. To check for the authentication, you can perform a GET request on /api/v1/security/principals/self :

 $ curl https://stream.example.com/api/v1/security/principals/self --cert client.pem --key client.key -H "Accept: application/json"

Possible responses are:

HTTP Response code Additional information
200 The login information were correct
401 Authentication error, please refer to the response body for more details

X509 authentication does not open a session: the certificate must be presented on every call.

Authenticating using OpenID Connect

When X-API-IDPROV names an OpenID Connect identity provider, Stream replies with a 200 response whose body is the authorization URL of that provider. The authentication is completed in a browser, after which Stream opens a session for the principal.

Handling next authentications using the Play Session

Once a successful authentication is done with credentials or OpenID Connect, the API generates a cookie called "PLAY_SESSION". This cookie holds the authentication information that was used to make the first login. To save its value for later use, just append -c cookies.txt to the previous curl request. Instead of using the credentials as headers at each API call, you can use the cookie :

 $ curl https://stream.example.com/api/v1/security/principals/self -b cookies.txt -H "Accept: application/json"

Every authenticated response also carries an X-Stream-Id header holding the identifier of the authenticated principal. A client can send this header back on its next calls: if the session it relied on has expired, Stream replies with a 401 SEC-AUTH-009 error instead of processing the request as anonymous.

Handling the CSRF Token

A CSRF token is required when all the following are true:

  • The request method is not GET.
  • The request is authenticated through the PLAY_SESSION cookie.

Requests authenticated with the X-API-ID and X-API-KEY headers or with an X509 certificate do not need a CSRF token. REST API are usually stateless and should not need cookies, so the authentication using API-ID and API-KEY should be preferred.

If a CSRF token is needed but not provided, Stream replies with a 401 response and a SEC-AUTH-002 error:

{
  "error": "SEC-AUTH-002",
  "message": "Invalid credentials or principal does not exist",
  "title": "Invalid credentials or principal does not exist",
  "detail": "<identifier>",
  "status": 401
}

When using the session cookie, retrieve the token value from the csrf-token cookie and send it back in a Csrf-Token header, along with the cookies.

First, authenticate and save the cookies:

 $ curl https://stream.example.com/api/v1/security/principals/self -H "X-API-ID: <identifier>" -H "X-API-KEY: <password>" -c cookies.txt

The cookies.txt file now holds the PLAY_SESSION and csrf-token cookies. Then send the token value in the Csrf-Token header:

 $ curl https://stream.example.com/api/v1/security/principalinfos -H "Content-Type: application/json" -H "Csrf-Token: <csrf-token cookie value>" --data '{"identifier": "test-user", "roles": ["<role>"]}' -b cookies.txt -c cookies.txt