Skip to content

Securing APIs

You can protect and integrate a web API with the CERN Single Sign-On by configuring it as an OAuth2 Resource Server. This is a widely used standard and you will find trusted libraries that support it for almost any programming language.

General recommendations

In order to make a secure integration with the CERN SSO make sure to follow these recommendations:

  1. Verify the token signatures: most libraries will require you to do that, you will find the public keys for your configuration in the following URL: https://auth.cern.ch/auth/realms/cern/protocol/openid-connect/certs
  2. Validate the audience (aud) of bearer tokens: it must match your Client ID. If you skip this step, you will be accepting any valid token for any CERN application.
  3. Verify the user roles if needed, by checking the cern_roles token claim.

Server configuration with cernsso_apache

Our Puppet module cernsso_apache can configure an Apache web server as an OAuth2 Resource Server. If you are using Apache to expose an API or any web service that needs to be accessed programmatically, this will allow other services to authenticate to your service by following web standards and using trusted libraries. Our module will include all the specific configuration for the CERN SSO automatically, including the recommendations from above.

Here are some configuration examples:

Directory server

Use this configuration for protecting files or CGI scripts.

class { 'cernsso_apache':
    client_id               => 'my-website',   # Your Client ID, as in the Application Portal
    server_type             => 'directory',
    document_root           => '/var/www/my-website'
    required_role           => 'default-role',
    enable_relying_party    => false,
    enable_resource_server  => true,
    resource_server_paths   => ['/'],
}

You can read session information in your scripts from the HTTP headers set by the Apache proxy, you will find more information about that in the module documentation.

Proxy server

Use this configuration to configure Apache as a reverse proxy for a locally running API. The API can be treated as a black box, and our module will configure authentication and authorisation for it. You can also read session information in the API from the HTTP headers sent by the Apache proxy, you will find more information about that in the module documentation.

class { 'cernsso_apache':
    client_id               => 'my-website',  # Your Client ID, as in the Application Portal
    required_role           => 'default-role',
    localapp_port           => 3000,
    enable_relying_party    => false,
    enable_resource_server  => true,
    resource_server_paths   => ['/'],
}

Registering your application

Register your API as an OpenID-Connect (OIDC) client here. Depending on who will use it it can be a public or a confidential client.

  • Public client: anyone at CERN will be able to get a token, you have to manage access by checking cern_roles.
  • Confidential client: you will need to store a Client Secret in every client accessing the API, and use it to get a valid token.

You can choose this with the option "My application cannot store a client secret safely".

Client configuration

APIs can be accessed by services (automatically) or by users (interactively). We provide different tools for each use case.

Automatic access

  • If you registered your server application as a confidential client (i.e. you have a Client ID and a Client Secret), you can get tokens using the standard OAuth2 Client Credentials Grant or the CERN Api-Access endpoint with the same Client ID and Secret. You have to tick the box "My application will need to get tokens using its own Client ID and Secret" in the application registration.

  • In other cases, you or your user will have to register a new application to use it as the API client by ticking the box "My application will need to get tokens using its own Client ID and Secret". Then use the CERN Api-Access endpoint.

Interactive access

Warning

This workflow has been added recently and is still under development. If you get the following error: Client is not allowed to initiate OAuth 2.0 Device Authorization Grant. The flow is disabled for the client. please open a support ticket and we will fix your client.

Register your application as a public client. Then any user will be able to get access using OAuth2 Device Authorization Grant or auth-get-user-token (this command is available in the package auth-get-sso-cookie). You can see how it works in the following example.

$ auth-get-user-token -c device-code-flow-test -o token.txt -x
$ token=$(<token.txt)
$ curl -X PUT "https://myapi.cern.ch/api/foobar" -H  "authorization: Bearer $token" -d "{\"foo\": \"bar\"}"

If you run this in a bash script with a registered Client ID, the user will see something like the following output:

User code: HCTK-VTVK
Please open the following link in your web browser:
https://auth.cern.ch/auth/realms/cern/device?user_code=HCTK-VTVK

Sign in using the link above and press enter to continue

They will be able to log in using the link in the terminal output and following the instructions to get a valid token for your API. Usually they can open the link in their main browser session, so they don't have to input their credentials again if they are already logged in.

Cookies and other alternatives

Cookies or other authentication protocols (e.g. SAML) are not a supported authentication mechanism for APIs when used together with the CERN Single Sign-On. We are aware that many older services used this, and their client integration was officially supported with the cern-get-sso-cookie tool. Clients for these tools can migrate to auth-get-sso-cookie, but this authentication flow will not be supported for newly developed APIs.

Kerberos

Kerberos is supported for the context of interactive access, with OAuth2 Device Authorization Grant or auth-get-user-token when a user logs in using a web browser window.

We don't support the development of automatic integrations (e.g. cron jobs) that exchange Kerberos sessions with Single Sign-On tokens.