On this page

Access Manager v3 API for C SDK

Access Manager v3 (PAM) lets your servers grant PubNub clients time-limited tokens with embedded permissions, instead of exposing your keyset directly. A single pubnub_grant_token() call can cover any mix of resource types:

  • channels
  • groups (channel groups)
  • uuids (other users' App Context metadata)

each granted either by exact resource name or by a RegEx pattern, with different permission levels per resource, all in one request. A token can be restricted to a single client through authorized_uuid and always carries a ttl after which it stops working.

Access Manager is compiled in only when the SDK is built with PUBNUB_ENABLE_PAM, which itself requires PUBNUB_ENABLE_CRYPTO:

PUBNUB_ENABLE_PAM requires PUBNUB_ENABLE_CRYPTO

Access Manager's request signing depends on the crypto provider. A build configured with PUBNUB_ENABLE_PAM=ON and PUBNUB_ENABLE_CRYPTO=OFF fails at CMake configure time with a fatal error, before any source file compiles. Enable PUBNUB_ENABLE_CRYPTO in every build that enables PUBNUB_ENABLE_PAM.

Requires Secret Key authentication

Granting permissions to resources should be done by administrators whose SDK instance has been initialized with a Secret Key (available on the Admin Portal on your app's keyset).

Secure your secret_key

Anyone who has your secret_key can grant and revoke permissions on every resource in your app. Never let secret_key be discovered, never place it in client-side code, and deliver it to your servers only over a secure channel. Once a context has a non-empty secret_key and the build enables PUBNUB_ENABLE_PAM, the SDK automatically signs every request that context sends. This includes grant, revoke, and everything else. There is no separate function to call to sign a request, and no way to opt out of signing while secret_key is set.

Grant token

Requires Access Manager add-on

This function requires that the Access Manager add-on is enabled for your key in the Admin Portal. Read the support page on enabling add-on features on your keys.

pubnub_grant_token() asks the server to issue a token with an embedded access-control list. Permissions are bits from pubnub_access_permission_t, OR'd together and attached to a resource name or pattern through pubnub_access_resource_permission_t.

Method(s)

#include <pubnub/features/access.h>

pubnub_future_t pubnub_grant_token(pubnub_context_t* ctx, const pubnub_grant_token_opts_t* opts);

Permission bits (pubnub_access_permission_t), combined with bitwise OR into a uint32_t:

ValueNumericMeaning
PUBNUB_ACCESS_READ
1
Read messages and presence events.
PUBNUB_ACCESS_WRITE
2
Publish messages.
PUBNUB_ACCESS_MANAGE
4
Add or remove channels in channel groups.
PUBNUB_ACCESS_DELETE
8
Delete messages from history.
PUBNUB_ACCESS_CREATE
16
Create resources (App Context).
PUBNUB_ACCESS_GET
32
Read resource metadata (App Context).
PUBNUB_ACCESS_UPDATE
64
Update resource metadata (App Context).
PUBNUB_ACCESS_JOIN
128
Join a channel (presence).

These values match the wire format directly. For example, PUBNUB_ACCESS_READ combined with PUBNUB_ACCESS_WRITE serializes as 3. Not every bit is meaningful for every resource type. See Manage Permissions with Access Manager v3 for the resource-to-permission mapping the server enforces.

Each resource entry (pubnub_access_resource_permission_t):

ParameterDescription
name
Type: const char*
Required, borrowed, NUL-terminated. An exact resource name, or a RegEx pattern string when the entry is placed in one of the pattern arrays below (for example "^chat\\..*$").
permissions
Type: uint32_t
One or more pubnub_access_permission_t values, combined with bitwise OR.

Grant options (pubnub_grant_token_opts_t):

* required
ParameterDescription
ttl *
Type: uint32_t
Minutes the token stays valid. Valid range is 1 to 43200 (30 days). 0 is rejected immediately with PUBNUB_ERR_INVALID_ARGUMENT, before any network call. There is no default.
channels
Type: const pubnub_access_resource_permission_t*
Exact channel permissions.
channel_count
Type: size_t
Entries in channels.
groups
Type: const pubnub_access_resource_permission_t*
Exact channel-group permissions.
group_count
Type: size_t
Entries in groups.
uuids
Type: const pubnub_access_resource_permission_t*
Exact uuid (App Context) permissions.
uuid_count
Type: size_t
Entries in uuids.
channel_patterns
Type: const pubnub_access_resource_permission_t*
RegEx pattern channel permissions.
channel_pattern_count
Type: size_t
Entries in channel_patterns.
group_patterns
Type: const pubnub_access_resource_permission_t*
RegEx pattern channel-group permissions.
group_pattern_count
Type: size_t
Entries in group_patterns.
uuid_patterns
Type: const pubnub_access_resource_permission_t*
RegEx pattern uuid permissions.
uuid_pattern_count
Type: size_t
Entries in uuid_patterns.
authorized_uuid
Type: const char*
Restricts the token to one client's uuid. Left NULL, the token can be used by any client that presents it.
meta
Type: const char*
A JSON metadata string embedded in the token and readable back after parsing.
timeout_ms
Type: uint32_t
Per-request timeout override. When non-zero, takes priority over the context-level transaction_timeout_ms.

PUBNUB_GRANT_TOKEN_OPTS_INIT zero-initializes every field, including ttl. Set ttl explicitly on every call, because the zero it starts at is itself an invalid value.

At least one permission is required

pubnub_grant_token() requires a permission on at least one resource or pattern. A call where channels, groups, uuids, channel_patterns, group_patterns, and uuid_patterns are all empty fails immediately with PUBNUB_ERR_INVALID_ARGUMENT.

C-family contract

  • Header#include <pubnub/features/access.h>
  • Typespubnub_grant_token_opts_t, pubnub_access_resource_permission_t, pubnub_access_permission_t
  • Prerequisite — a context created or initialized with subscribe_key, publish_key, and secret_key set. See Identity and keys.
  • Feature flag — compiled in only when PUBNUB_ENABLE_PAM is enabled.
  • Ownership / lifetime — every string and array field on pubnub_grant_token_opts_t is borrowed. The name values inside channels, groups, uuids, and the three pattern arrays, plus authorized_uuid and meta, must all remain valid until pubnub_grant_token() returns.
  • Blocking — starts asynchronous work and returns a pubnub_future_t immediately. Validation failures such as a missing or out-of-range ttl, no permissions, or missing keys come back as an already-failed future with no network call made.

Sample code

#include "pubnub/pubnub.h"

#include <stdio.h>

int main(void)
{
/* 1. Configure and create the client. secret_key is required for
Access Manager and must never be shipped in client-side code. */
pubnub_config_t cfg = pubnub_config_defaults();
cfg.publish_key = "demo";
cfg.subscribe_key = "demo";
cfg.secret_key = "demo";
cfg.user_id = "admin-user";

pubnub_context_t* ctx = pubnub_create(&cfg);
show all 63 lines

Returns

pubnub_grant_token() returns a pubnub_future_t. Once pubnub_future_status() reports PUBNUB_OK, call pubnub_grant_token_result() to read the issued token:

ParameterDescription
token
Type: pubnub_string_view_t
The issued token. Valid until you call pubnub_future_release() on the future that produced it. Read or copy token.ptr/token.len before releasing.

Other examples

Grant using an async callback

pubnub_grant_token() works the same way with any of the three future-consumption styles. This example uses pubnub_async() instead of cooperative polling:

#include "pubnub/pubnub.h"

#include <stdio.h>

static volatile int s_done;

static void on_grant(pubnub_future_t future, pubnub_res_t status, void* user_data)
{
(void)user_data;

if (PUBNUB_OK == status) {
pubnub_grant_token_result_t r = pubnub_grant_token_result(future);
printf("Token: %.*s\n", (int)r.token.len, r.token.ptr);
} else {
pubnub_string_view_t err = pubnub_response_error_message(future);
show all 67 lines

Error responses

Validation failures never reach the network. They come back as an already-failed future:

ConditionResult
opts is NULL
PUBNUB_ERR_INVALID_ARGUMENT
ttl is 0 or exceeds 43200
PUBNUB_ERR_INVALID_ARGUMENT
no permission set on any resource or pattern
PUBNUB_ERR_INVALID_ARGUMENT
the context or its configuration is invalid
PUBNUB_ERR_INVALID_ARGUMENT
publish_key or secret_key is not set on the context
PUBNUB_ERR_INVALID_ARGUMENT
a required allocator/serialization provider is missing
PUBNUB_ERR_NOT_INITIALIZED
the request queue is full
PUBNUB_ERR_QUEUE_FULL
an internal allocation fails
PUBNUB_ERR_OUT_OF_MEMORY
the platform provider's wall_clock_ms callback is missing or reports 0 (no RTC / not yet NTP-synchronized), so the PAM request cannot be timestamp-signed
PUBNUB_ERR_NO_WALL_CLOCK

A server-side rejection completes the future with PUBNUB_ERR_SERVER. Call pubnub_response_service_error() to read the normalized detail. For Access Manager responses specifically, the resulting pubnub_service_error_t.source field is populated. It is empty for every other endpoint's error shape. See Retrieving server error detail.

Revoke token

Requires Access Manager add-on

This function requires that the Access Manager add-on, and specifically token revocation, is enabled for your key in the Admin Portal. Open your app's keyset and mark the Revoke v3 Token checkbox in the ACCESS MANAGER section.

pubnub_revoke_token() disables a token you previously issued with pubnub_grant_token(), invalidating every permission embedded in it. Use it only for tokens with a ttl of 30 days or less. For a longer-lived token, contact PubNub support.

Method(s)

#include <pubnub/features/access.h>

pubnub_future_t pubnub_revoke_token(pubnub_context_t* ctx, const pubnub_revoke_token_opts_t* opts);

Revoke options (pubnub_revoke_token_opts_t):

* required
ParameterDescription
token *
Type: const char*
Borrowed, NUL-terminated. The token to revoke.
timeout_ms
Type: uint32_t
Per-request timeout override, same semantics as grant's timeout_ms.

PUBNUB_REVOKE_TOKEN_OPTS_INIT zero-initializes both fields. Set token explicitly before calling.

C-family contract

  • Header#include <pubnub/features/access.h>
  • Typespubnub_revoke_token_opts_t
  • Prerequisite — a context configured with subscribe_key and secret_key set.
  • Feature flag — compiled in only when PUBNUB_ENABLE_PAM is enabled.
  • Ownership / lifetimetoken is borrowed and must remain valid until pubnub_revoke_token() returns.
  • Blocking — starts asynchronous work and returns a pubnub_future_t immediately. A missing token or missing secret_key fails immediately with no network call made.

Sample code

#include "pubnub/pubnub.h"

#include <stdio.h>

int main(void)
{
/* 1. Configure and create the client. */
pubnub_config_t cfg = pubnub_config_defaults();
cfg.subscribe_key = "demo";
cfg.secret_key = "demo";
cfg.user_id = "admin-user";

pubnub_context_t* ctx = pubnub_create(&cfg);
if (NULL == ctx) {
printf("pubnub_create failed\n");
show all 46 lines

Returns

pubnub_revoke_token() returns a pubnub_future_t. There is no result struct. A successful revoke completes the future with PUBNUB_OK and nothing else to read.

Error responses

ConditionResult
opts is NULL
PUBNUB_ERR_INVALID_ARGUMENT
token is NULL or empty
PUBNUB_ERR_INVALID_ARGUMENT
the context or its configuration is invalid
PUBNUB_ERR_INVALID_ARGUMENT
secret_key is not set on the context
PUBNUB_ERR_INVALID_ARGUMENT

A server-side rejection completes the future with PUBNUB_ERR_SERVER. Read the detail the same way as for Grant token. See Retrieving server error detail.

Parse token

pubnub_parse_token() decodes a token and exposes the permissions embedded in it. Use it for debugging, or to inspect a token received from a grant response or another source before deciding whether to use it.

This call is synchronous and local, not a network request

Unlike pubnub_grant_token() and pubnub_revoke_token(), pubnub_parse_token() returns a pubnub_res_t directly, not a pubnub_future_t. It decodes the token's base64url-encoded CBOR payload locally and never contacts the server.

Method(s)

#include <pubnub/features/access.h>

pubnub_res_t pubnub_parse_token(pubnub_context_t* ctx,
const pubnub_parse_token_opts_t* opts,
pubnub_parsed_token_t* out_result);

pubnub_parsed_token_resource_t pubnub_parsed_token_channel_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_group_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_uuid_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_channel_pattern_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_group_pattern_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_uuid_pattern_at(pubnub_context_t* ctx, size_t index);

Parse options (pubnub_parse_token_opts_t):

* required
ParameterDescription
token *
Type: const char*
Borrowed, NUL-terminated. The base64url-encoded token string to decode.

PUBNUB_PARSE_TOKEN_OPTS_INIT zero-initializes the struct. Set token explicitly.

C-family contract

  • Header#include <pubnub/features/access.h>
  • Typespubnub_parse_token_opts_t, pubnub_parsed_token_t, pubnub_parsed_token_resource_t
  • Prerequisite — none of the Access Manager keys are required. Parsing does not touch secret_key or publish_key, and it does not make a request.
  • Feature flag — compiled in only when PUBNUB_ENABLE_PAM is enabled.
  • Ownership / lifetime — the decoded resource data backing the six accessor functions lives on ctx, not on your out_result. It stays valid until the next pubnub_parse_token() call on the same context, or until pubnub_destroy()/pubnub_deinit(). The scalar fields you receive by value in out_result (version, timestamp, ttl, authorized_uuid, and the six *_count fields) are yours. Their *_count values, though, describe only that parse. Read them and call the accessors before parsing a second token on the same context.
  • Blocking — synchronous, local only. No network call, no future.
One parsed token per context

Calling pubnub_parse_token() again on the same context replaces the previously decoded data that the six indexed accessor functions read from. Your own out_result struct is unaffected, but its *_count fields become stale as loop bounds for the accessors once a second parse has happened on that context. Read everything you need, including every accessor call, from the first parse before parsing another token on the same ctx.

Sample code

#include "pubnub/pubnub.h"

#include <stdio.h>

int main(void)
{
/* 1. Configure and create the client. No secret_key is needed to parse. */
pubnub_config_t cfg = pubnub_config_defaults();
cfg.subscribe_key = "demo";
cfg.user_id = "example-parse";

pubnub_context_t* ctx = pubnub_create(&cfg);
if (NULL == ctx) {
printf("pubnub_create failed\n");
return 1;
show all 77 lines

Returns

pubnub_parse_token() returns PUBNUB_OK on success and populates out_result (pubnub_parsed_token_t):

ParameterDescription
version
Type: int32_t
Token format version.
timestamp
Type: uint64_t
Token creation time, Unix seconds.
ttl
Type: uint32_t
Token time-to-live, in minutes, as embedded in the token.
authorized_uuid
Type: pubnub_string_view_t
Empty (.len == 0) if the token was granted without an authorized_uuid restriction.
channel_count
Type: uint32_t
Number of exact channel permissions. This bounds pubnub_parsed_token_channel_at().
group_count
Type: uint32_t
Number of exact channel-group permissions. This bounds pubnub_parsed_token_group_at().
uuid_count
Type: uint32_t
Number of exact uuid permissions. This bounds pubnub_parsed_token_uuid_at().
channel_pattern_count
Type: uint32_t
Number of pattern channel permissions. This bounds pubnub_parsed_token_channel_pattern_at().
group_pattern_count
Type: uint32_t
Number of pattern channel-group permissions. This bounds pubnub_parsed_token_group_pattern_at().
uuid_pattern_count
Type: uint32_t
Number of pattern uuid permissions. This bounds pubnub_parsed_token_uuid_pattern_at().

Each of the six indexed accessor functions returns a pubnub_parsed_token_resource_t:

ParameterDescription
name
Type: pubnub_string_view_t
The resource name or pattern, aliasing data owned by ctx. See the ownership note above.
permissions
Type: uint32_t
The permission bits granted to this resource, as pubnub_access_permission_t values combined with bitwise OR.

On failure, out_result is zero-initialized rather than left untouched.

Error responses

ValueMeaning
PUBNUB_OK
Decoded successfully. out_result is populated.
PUBNUB_ERR_INVALID_ARGUMENT
opts->token is NULL or empty.
PUBNUB_ERR_SERIALIZATION
The token is not valid base64url, or does not decode to a valid token structure.

Set auth token

A client that receives a token attaches it to its own context with pubnub_set_auth_token() so that every subsequent request from that context carries the token. The token can come from your server's pubnub_grant_token_result_t.token, or from any other channel you use to deliver tokens. This function is declared in client.h, not access.h. The full pubnub_config_t/runtime-setter story, including pubnub_get_auth_token(), is documented in Runtime updates. This section covers only how it applies to a token received from Access Manager.

Method(s)

#include <pubnub/client.h>

pubnub_res_t pubnub_set_auth_token(pubnub_context_t* ctx, const char* token);
const char* pubnub_get_auth_token(const pubnub_context_t* ctx);

C-family contract

  • Header#include <pubnub/client.h>
  • Prerequisite — an already created or initialized context.
  • Ownership / lifetime — on a pubnub_create-based context, pubnub_set_auth_token() deep-copies token. On a pubnub_init-based context, it borrows it. pubnub_get_auth_token() returns a context-owned pointer, valid until the next pubnub_set_auth_token() call or context teardown. Do not free it.
  • Blocking — synchronous, no I/O.

This snippet is derived from the function declarations in client.h. There is no dedicated Access Manager example that exercises it.

Sample code

#include <pubnub/client.h>

static void apply_granted_token(pubnub_context_t* ctx, const char* token)
{
pubnub_res_t res = pubnub_set_auth_token(ctx, token);
if (PUBNUB_OK != res) {
/* token was rejected -- inspect res with pubnub_res_str() */
return;
}

const char* current = pubnub_get_auth_token(ctx);
(void)current;
}

Returns

pubnub_set_auth_token() returns PUBNUB_OK on success, PUBNUB_ERR_NOT_INITIALIZED if ctx is not initialized, or PUBNUB_ERR_OUT_OF_MEMORY if the deep-copy allocation fails (on pubnub_create-based contexts). pubnub_get_auth_token() returns the context's current auth_token, or NULL if none is set.