Authentication and API-keys#

To use the API, the user has to obtain an API-key. API-keys should be issued for each use case, and if possible restricted to the roles/customers needed only for that use case.

API-keys are based on user permissions, so any API-keys permissions will be constrained by the permissions of its user. In addition, each API-key can be constrained to a subset of roles and/or customers.

An API-key is constrained both on time and source network - e.g. can be valid for 3 months, and only valid from one single IP or set of IP networks/addresses.
API-keys which have expired on time can be renewed for another time period.

Creating an API-key#

Users can create or renew their own API-keys in the Argus GUI under User Preferences, if API-key usage has been enabled for their user. If API-key usage is not enabled for your user, contact mnemonic.

To obtain unconstrained API-keys (not limited in time and/or IP-range), this has to be done by an administrator, and is normally not granted for end users.

Using an API-key#

To use an API-key, add the API-key as a HTTP header Argus-API-Key.

Using e.g. curl, this can be done e.g.

curl --header "Argus-API-Key: 1/2/mysecretapikey" https://api.mnemonic.no/assets/v1/host

Using an invalid or expired API-key will cause Argus to respond with a 401 Unauthorized message.

If the key is expired, or used from the wrong source IP, the response should contain an error message to that effect.

Session authentication#

If needing to run a REST client with an authenticated session (e.g. to run with higher Security Level than given by use of API-key), the REST client has to perform a session authentication.

To do this, choose an authentication method which is

The documentation for authenticating using this method can be found in swagger, underauthentication/v1/method/authenticate.

When successful, the authentication request will set the cookie argus_session. By including this cookie in the subsequent requests, the created session will be used.

When using session authentication, the client should delete the session at the end, using :

DELETE https://api.mnemonic.no/authentication/v1/logout

Signature authentication#

Using JWT signatures is another way of authenticating to Argus, which allows a higher security level, while performing per-request authentication instead of session authentication.

To use JWT tokens for authentication, the user must have enabled signature based authentication, and must have created or uploaded a public key which is used to verify the signature.

Each key may be constrained to a particular IP network, or to a subset of the users available functions or customers.

Note

  • Signature-based authentication requires a unique signature per request. The signatures cannot be reused for multiple requests.

  • The JWT signature must contain valid claims on a format as specified below. If required claims are not met, the request is rejected with a 401 error.

  • One of these claims is the client timestamp (in milliseconds since epoch). Argus allows for a certain clock skew (up to 2 hours), but will pin the client to this clock skew, so the clients clock cannot “jump around”.

When using signature-based authentication, please make sure that your client has a stable clock, which should be synchronized using NTP.

Required claims#

required claims#

Claim

Value

uri

The URI of the current request. Only the base URI is considered, any query parameters are ignored.

timestamp

The current timestamp of the client, at the time of the request, in milliseconds since epoch.

nonce

A random string

Generating a valid authentication header#

The JWT token should be generated using algorithm ES256 (EC key) or RS256 (RSA key) with the three claims above.

You will also need the ID of your key, which is in the format <domain>/<username>/<key-idx>, e.g. MNEMONIC/myusername/1.

The key index of your key is the idx returned when uploading the public key.

When downloading a generated private key from Argus, the index is always 0.

The following code should create a valid signature header:

public String createSignature(String keyID, PrivateKey privateKey, String uri, long timestamp) throws NoSuchAlgorithmException {
  byte[] nonceBytes = new byte[64];
  SecureRandom.getInstanceStrong().nextBytes(nonceBytes);
  String nonce = Base64.getEncoder().encodeToString(nonceBytes);

  String signature = Jwts.builder()
    .claim("uri", uri)
    .claim("nonce", nonce)
    .claim("timestamp", timestamp)
    .signWith(SignatureAlgorithm.RS256, privateKey)
    .compact();
  return String.format("%s:%s", keyID, signature);
}

The JWT token should be appended to your request using the header Argus-Signature, e.g:

Argus-Signature: MNEMONIC/myusername/1:eyJhbGciOiJFUzI1NiJ9.eyJ1cmkiOiJodHRwOi8vbXkudXJpIiwibm9uY2UiOiJub25jZSIsInRpbWVzdGFtcCI6MTAwMDB9.iRgtjz7Jr3gikS3hRHZHfYU8Lbt8vjclJP9To2B-9L8eVTHWcyMuWkEhKGxD2lhoUxgnJgWxd1IyuqrYlkRjwQ