SymetryML Documentation

SymetryML REST API Security

SymetryML REST Request Authentication

The SymetryML REST API allows you to authenticate your requests. The API’s authentication is based on a "message-authentication code" signature created using specific parts of the REST API HTTP request.

Message authentication code (MAC) provides a way to verify the integrity of information sent in a REST request based on a secret key known only to the request sender and receiver. Because only two parties know the secret key, validating the MAC signature also authenticates the corresponding REST request. For this reason, each SymetryML API account has a secret key associated with its SymetryML key ID that is used to create a MAC signature for each REST request. The SymetryML server uses this secret key to verify signatures and authenticate all requests.

Authentication Header

The SymetryML REST API uses the HTTP Authorization header to pass authentication information to the server. The signature is an HMAC-SHA256 (HMAC-SHA2, RFC 4868) of a string built from the request.

Changed in SymetryML 7.0. The secret key is no longer part of the string to sign; it is only the HMAC key. HMAC-SHA1 is no longer accepted, and every request must send sym-version with major version 7. Clients written for 6.x get 401 Invalid Signature or 400 until they are upgraded. See Protocol Version Header.

HeaderDescription
AuthorizationSignature
SignatureBase64( HMAC-SHA256( Base64Decode(SecretKey), UTF-8-Encoding-Of( StringToSign ) ) )
StringToSignHTTP-Verb + "\n" + Content-MD5 + "\n" + Sym-Date + "\n" + SymetryML-customer-Id + "\n" + RequestBody + "\n" + CanonicalizedResource + "\n" + URLQueryParameters + "\n"
SecretKeyThe customer's SymetryML secret key, a Base64-encoded 128-bit key. The decoded bytes are the HMAC key. The secret key never appears in the string to sign.
Content-MD5Base64 of the MD5 digest of the UTF-8 request body. An empty string when there is no body; the newline that follows it is still added.
Sym-Date formatSee the section covering Date Header.
CanonicalizedResource<HTTP-Request-URI, from the protocol name up to the query string>
URLQueryParametersAny URL query parameters used in the REST request. If no query parameters are present, do not add null or a new line "\n".
RequestBodyJSON request body. If there is no request body, omit this along with the newline ("\n") that follows it.
sym-versionProtocol version of the client. Required; must be 7.x. Not part of the string to sign. See Protocol Version Header.
sym-clientThis parameter is not mandatory and not used in computing the string to sign, but is used when compiling logging statistics about the data source and streaming API. For more details please consult the DS Log section.

Protocol Version Header

Every request must carry a sym-version header whose major version is 7, for example:

sym-version: 7.0

Any minor version is accepted. A request with no sym-version header, or with a major version other than 7, is refused with 400 BAD REQUEST before the signature is checked. The message names the version the server requires. WebSocket messages carry the same version in their header; see WebSocket API.

SymetryML 7.0 has no backward compatibility with 6.x clients: the signature and the encrypted body format both changed. Upgrade pymetry, the web UI, the Java client and any custom client together with the server.

Encrypted Request and Response Bodies

Some request bodies and response values carry credentials (data source definitions, federation information, fusion cell information) and are encrypted with the customer's secret key, so they are never sent in the clear even without HTTPS. The SymetryML 7.0 format is:

v2:Base64( nonce[12] || AES-GCM-128(key, nonce, UTF-8 plaintext) || tag[16] )
PartDescription
v2:Format prefix. Required. A receiver reads everything up to the first : and refuses any other prefix.
nonce12 random bytes, drawn fresh for every encryption. Never reuse a nonce with the same key.
keyThe Base64-decoded secret key (16 bytes).
tagThe 128-bit GCM authentication tag, appended to the cipher text. A modified payload or a wrong key fails decryption.

No additional authenticated data is used. Federation invitations are encrypted with a password instead of the secret key: the password (at most 16 characters) is zero-padded to a 16-byte key, and the output has the same v2: format.

The pre-7.0 format (bare Base64, AES/CBC/PKCS5Padding with a fixed initialization vector) is no longer accepted. A body in that format is refused with 400 BAD REQUEST.

SymetryML Date Header

Each SymetryML REST request must contain a SymetryML Date header. The content of this header is a date and time based on the Universal Coordinated Time/Greenwich Mean Time (UTC/GMT) time zone. This header is called sym-date.

The SymetryML Date header must:

  • Follow this syntax:
yyyy-MM-dd HH:mm:ss;nanoseconds

For example:

2014-07-31 08:01:07;1245
  • Not be 5 minutes or more behind the server time
  • Not be more than 1 minute ahead of the server time.

Authentication Errors

If the signature does not verify, the server returns a 401 (UNAUTHORIZED) response with the status string Invalid Signature.

When the server runs with debug logging, the response also contains a stringToSign entity: the string the server signed when it checked the request. Compare it with the string your client signed to find the difference. In normal operation the entity is not sent.

The following shows an example of an unauthorized response from a server with debug logging on.

{
      "statusCode":"UNAUTHORIZED",
      "statusString":"Invalid Signature",
      "values":{
            "stringToSign":"DELETE\\n\\n2013-05-22 18:13:38\\nc1\\nhttp://192.168.0.19:8080/symetry/rest/c1/projects/r1\\n"
      }
}

Authentication Error Codes

To help you identify and resolve authentication issues quickly, the SymetryML REST API supports a variety of error codes. The following table describes the supported error codes.

API Error Codes
Error CodeHTTP CodeDescription
Md5 do not match400MD5 of the request body is invalid.
Invalid User401Server does not know this user.
Invalid Signature401Authentication header signature is invalid.
Invalid Signature: too many authentication error, disabling user credential401Too many failed signatures for this user; the user's credential is disabled.
Unlicensed Software401The server license is missing or expired.
Too many users401The server has more users than its license allows.
Authorization header is null400Authorization header is missing from the request.
sym-date header is null400SymetryML date header is missing from the request.
Missing sym-version header; … / Client protocol version […] is not supported; …400The sym-version header is missing or its major version is not 7. See Protocol Version Header.
Please update your server time, it is likely out of sync with UTC400Date in the request is more than 5 minutes before the server time or more than 1 minute after it. Check the time configuration on your client.
Invalid Date format: …400Format of the SymetryML date header is invalid. See the section SymetryML Date Header for information about the appropriate format to use.
Duplicate request.403A request with the same signature was already received. Every request needs its own sym-date, and so its own signature.
Redis store is not in SymetryML 7.0 format …503The server was upgraded from 6.x but its stored credentials were not migrated. Every request is refused until the migration is done; see the Installation Guide.

Cross-Origin Resource Sharing (CORS)

By default the REST API sends no CORS headers, so a browser page served from a different origin cannot call it directly. CORS is opt-in: start the SymetryML JVM with

-Dsml.rest.cors=true

See SymetryML REST Configuration for where to set this in a Docker deployment.

When the flag is on, every REST response carries the following headers:

HeaderValue
Access-Control-Allow-Origin*
Access-Control-Allow-MethodsGET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-HeadersContent-MD5, Sym-date, Customer-ID, Authorization, sym-version, Content-Type
Access-Control-Max-Age86400

The browser's preflight OPTIONS request is answered automatically and passes through the same filter, so preflight needs no additional configuration.

Note: Access-Control-Allow-Credentials is deliberately not sent. The API is request-signed with HMAC-SHA2 and uses no cookies or sessions, so a browser has no ambient credential to attach — a page can only call the API if it holds the customer's secret key. Bear in mind that a secret key placed in browser-side code is visible to anyone who loads that page.

APIs at-a-Glance

Please note that Every REST request that is made starts with the following canonical URL:

HTTPVERB /symetry/rest/{cid}

where:

  • {cid} is the customer ID.
  • HTTP VERB is a valid HTTP verb such as GET, PUT, POST, or DELETE.

On this page