Access Manager introduction
You can use Access Manager to generate time-limited tokens with permissions for individual resources such as channels, channel groups, or uuids. Once the permissions are granted, the token must be passed back to the clients. You can also revoke tokens, effectively removing all embedded permissions.
For more details, refer to Access Manager.
Signature Generation in Access Manager
The signature is used to verify if the request was signed with the secret key associated with the PubNub subscribe key.
- Signature is computed using HMAC+SHA256 with the user's secret key as the signing key.
- The signing message is composed of the HTTP method, publish key, request path, query string, and request body (or empty string) in the following format
{method}\n{pub_key}\n{path}\n{query_string}\n{body}. Note that{pub_key}is the publish key from Admin Portal — not the subscribe key. - Query parameters must be sorted lexicographically (case-sensitive) by a key. Duplicate keys are not allowed.
- Replace special characters in the query parameters using the
%xxescape. Letters, digits, and the characters_.-are never quoted. For example,~user/1_2.3-4should be encoded%7Euser%2F1_2.3-4. Uppercase characters in the percent escapes are required. In other words, all characters matching the RegEx/[^0-9a-zA-Z\-_\.]/must remain unencoded. - Space characters must be replaced by
%20(NOT the+character). - Each key-value pair must be separated by an ampersand (
&) character. - Unicode characters must be broken up into
UTF-8encoded bytes before percent-encoding.
# Example query string containing unicode characters
timestamp=1234567898&PoundsSterling=£13.37
# The same query string after sorting and percent-encoding
timestamp=1234567898&PoundsSterling=%C2%A313.37
- The request body must be appended to the message verbatim (byte-for-byte, as provided in the request).
The signing scheme described above is the current PubNub signature scheme and applies to all PubNub REST API requests. If your application was built against the older legacy signature scheme, see the legacy signature documentation.
Signature example — POST request (with body)
Each component is separated by a single newline character (\n). There are exactly four \n separators in every signing message regardless of whether a body is present.
In this example, the POST body is encoded with UTF-8 and appended verbatim. The body itself does not have a trailing newline.
POST\n demo\n /v3/pam/demo/grant\n PoundsSterling=%C2%A313.37×tamp=1234567898\n {"ttl":1440,"permissions":{"resources":{"channels":{"inbox-jay":3},"groups":{},"users":{},"spaces":{}},"patterns":{"channels":{},"groups":{},"users":{},"spaces":{}},"meta":{"user-id":"jay@example.com","contains-unicode":"The 🦝 test."}}}
Let's imagine the demo account's secret key is wMfbo9G0xVUG8yfTfYw5qIdfJkTd7A. The HMAC-SHA256 digest is Base64 URL-safe encoded (replacing + with - and / with _, and stripping trailing = padding), then prefixed with v2.. The expected signature for this request is: v2.hz8Vl68RhB0RyoUDYLQ7VP7hEP5qTZrjzqdEWZxE_4g.
Signature example — DELETE request (no body)
When there is no request body, {body} is an empty string. The \n separator before it is still required, so the signing message always ends with \n.
The trailing newline after timestamp=... represents the \n separator followed by the empty body string. Omitting it is a common source of the "Client and server produced different signatures" error on bodyless requests such as token revocation.