diff --git a/content/partials/types/_client_options.textile b/content/partials/types/_client_options.textile index 943c723fa2..d3f0e15ee7 100644 --- a/content/partials/types/_client_options.textile +++ b/content/partials/types/_client_options.textile @@ -10,7 +10,7 @@ h4. <%= partial partial_version('shared/_token_auth_methods') %> -- tlsTls:tls := _true_ A boolean value, indicating whether or not a TLS ("SSL") secure connection should be used. An insecure connection cannot be used with Basic authentication as it would lead to a possible compromise of the private API key while in transit. "Find out more about TLS":https://faqs.ably.com/are-messages-sent-to-and-received-from-ably-securely-using-tls
__Type: @Boolean@__ +- tlsTls:tls := _true_ A boolean value, indicating whether or not a TLS ("SSL") secure connection should be used. An insecure connection cannot be used with Basic authentication as it would lead to a possible compromise of the private API key while in transit. The JavaScript library uses the TLS version supported by the browser environment.In Node.js, the TLS version is determined by the Node.js runtime version. "Find out more about TLS":/docs/channels/options/encryption#tls
__Type: @Boolean@__ - clientIdClientIdclient_id:client_id := A client ID, used for identifying this client when publishing messages or for presence purposes. The @clientId@@client_id@@ClientId@ can be any non-empty string. This option is primarily intended to be used in situations where the library is instantiated with a key; note that a @clientId@@client_id@@ClientId@ may also be implicit in a token used to instantiate the library; an error will be raised if a @clientId@@client_id@ specified here conflicts with the @clientId@@client_id@@ClientId@ implicit in the token. "Find out more about client identities":/docs/auth/identified-clients
__Type: @String@__ diff --git a/src/pages/docs/auth/capabilities.mdx b/src/pages/docs/auth/capabilities.mdx index fd25089dc0..54ec81bc7a 100644 --- a/src/pages/docs/auth/capabilities.mdx +++ b/src/pages/docs/auth/capabilities.mdx @@ -7,7 +7,17 @@ API keys and Ably-compatible tokens, have a set of capabilities assigned to them API keys are long-lived, secret and typically not shared with clients. API key capabilities are configured using the [dashboard](https://ably.com/dashboard), or using the [Control API](/docs/platform/account/control-api). -Ably-compatible tokens are designed to be shared with untrusted clients, are short-lived, and can be configured and issued programmatically. See [selecting an authentication mechanism](/docs/auth#selecting-auth) to understand why token authentication is the preferred option in most scenarios. +Ably-compatible tokens are designed to be shared with untrusted clients, are short-lived, and can be configured and issued programmatically. For restricting client access to channels, tokens provide far more flexibility and security than API key capabilities. See [selecting an authentication mechanism](/docs/auth#selecting-auth) to understand why token authentication is the preferred option in most scenarios. + +### Capability changes and existing connections + + + +Once created, it's best to think of keys and tokens as being immutable. To modify the permissions granted to existing connections, the recommended approach is to use [token authentication](/docs/auth/token) and issue the client a new token with the updated permissions you want them to have. + +The one exception is if a key is revoked entirely, in which case all connections using that key (or a token derived from that key) will be forcibly terminated. See [token revocation](/docs/auth/revocation) for more information. ## Resource names and wildcards diff --git a/src/pages/docs/auth/index.mdx b/src/pages/docs/auth/index.mdx index 171144ce70..51949e95e5 100644 --- a/src/pages/docs/auth/index.mdx +++ b/src/pages/docs/auth/index.mdx @@ -22,6 +22,22 @@ redirect_from: Before a client or server can issue requests to Ably, such as subscribe to channels, or publish messages, it must authenticate with Ably. Authentication requires an Ably API key. +## Authentication terminology + +The following terminology helps explain authentication, authorization, and identification in the context of the Ably service: + +"Authentication" is the process of deciding, based on the presented credentials, whether or not an entity may interact with the Ably service. The credentials may be presented explicitly using [Basic Authentication](/docs/auth/basic) or [Token Authentication](/docs/auth/token), or in some cases the entity authenticating may prove possession of the credentials with a signed Token Request that is subsequently used to generate a valid token to be used for Token Authentication. When authenticating with Ably, the credentials are either an API key or an auth token. + +"Authenticated client" is a client of the Ably service that has been successfully authenticated. + +"Authorization" is the process of deciding whether or not a given entity (usually authenticated) is allowed to perform a given operation. In Ably, authorization for most operations is based on the [capabilities](/docs/auth/capabilities) associated with the key or token that was used to authenticate a client. + +"Identified client" is an authenticated client with a specific claimed client identity, or `clientId`, whose credentials are verified as confirming that identity. See the [identified clients](/docs/auth/identified-clients) documentation for more information. + + + ## Ably API keys Every Ably app can have one or more API keys associated with it in order to authenticate directly with Ably, or to issue tokens with. API keys can be created with different [capabilities](/docs/auth/capabilities) and any tokens issued using that API key can only permit a subset of those capabilities. diff --git a/src/pages/docs/auth/token.mdx b/src/pages/docs/auth/token.mdx index e2927166f7..7da22d1b33 100644 --- a/src/pages/docs/auth/token.mdx +++ b/src/pages/docs/auth/token.mdx @@ -7,11 +7,29 @@ Token authentication uses a trusted device with an [API key](/docs/auth#api-key) Token authentication is the recommended authentication method to use client-side as it provides more fine-grained access control and limits the risk of credentials being exposed. +## Access restrictions + +### Token-based client validation + +Token authentication enables you to validate client characteristics (such as origin, IP address, cookies, or any other client features) in your authentication server before issuing tokens. This provides flexible access control as you can implement any validation logic in your auth server as part of the token issuance process. + +### API key restrictions + +For cases where token authentication is impractical, Ably can add origin or IP address restrictions directly to API keys. However, this approach has significant limitations: + +- Less flexible than token authentication. +- Manual intervention required to modify restrictions. +- Enterprise support packages only: contact [Ably support](https://ably.com/support) if interested. +- Not a security boundary: origin headers can be easily spoofed, especially outside browser contexts. +- Permissive fallback: requests with no origin header are allowed when origin restrictions are set. + +For maximum security and flexibility, token authentication with server-side validation is the recommended approach. + Any of the following cause an SDK to use token authentication: -* An [`authUrl`](/docs/api/realtime-sdk/types#client-options) or [`authCallback`](/docs/api/realtime-sdk/types#client-options) is provided that returns an Ably-compatible token or an Ably [`TokenRequest`](/docs/api/realtime-sdk/types#token-request) -* [`useTokenAuth`](/docs/api/realtime-sdk/types#client-options) is true -* A [`token`](/docs/api/realtime-sdk/types#client-options) or [`tokenDetails`](/docs/api/realtime-sdk/types#client-options) property is provided +* An [`authUrl`](/docs/api/realtime-sdk/types#client-options) or [`authCallback`](/docs/api/realtime-sdk/types#client-options) is provided that returns an Ably-compatible token or an Ably [`TokenRequest`](/docs/api/realtime-sdk/types#token-request). +* [`useTokenAuth`](/docs/api/realtime-sdk/types#client-options) is true. +* A [`token`](/docs/api/realtime-sdk/types#client-options) or [`tokenDetails`](/docs/api/realtime-sdk/types#client-options) property is provided. Providing a literal `token` or `tokenDetails` is typically used for testing: since tokens are short-lived, in production you typically want to use an authentication method that allows the client library to renew the token automatically before the current token expires. @@ -1054,3 +1072,116 @@ When selecting an Ably SDK for implementing token authentication with Ably, you As basic authentication is primarily designed for authenticating a secure server, in this situation, and assuming the server is only used for authentication, it is more efficient to use the REST interface, as the overhead associated with maintaining a realtime connection, is not required to issue tokens. + +## Incremental authorization and reauth + +Ably's authentication uses a system of immutable tokens. Once created, tokens have a fixed set of [capabilities](/docs/auth/capabilities) that cannot be modified. However, there are scenarios where clients may need additional capabilities after their initial connection. + +### Reauthorization process + +When a client needs new capabilities, it can reauthorize by obtaining a new token from your auth server and calling [`auth.authorize()`](/docs/api/realtime-sdk/authentication#authorize). This upgrades the connection to use the new token without disrupting the existing connection or requiring reconnection. + +### Reauthorization strategies + +Choose the strategy that best fits your application architecture: + +#### Server-determined capabilities + +Best for applications with session management where the server maintains complete client state. + +Your auth server tracks the canonical list of capabilities each client should have. When the client requests a new token, the server generates it with the complete capability set. This is the most secure approach as the server is the single source of truth. + +#### Client-requested capabilities + +Best for applications where clients need to request specific additional capabilities. + +The client can request additional capabilities by including them in the token request: + +- With `authUrl`: Use `authParams` or `authHeaders` in [client options](/docs/api/realtime-sdk/types#client-options) to send capability requests. +- With `authCallback`: Construct a custom request to your server with the needed capabilities. + +Your server validates the request, updates its records of client capabilities, and issues a token with the complete capability set. + +#### Client-managed capabilities + +Best for stateless auth servers that cannot maintain client sessions. + +The client maintains its own list of needed capabilities and sends the complete list to the server on each token request. The server validates each capability before issuing the token. + +#### Signed capability storage + +Best for stateless servers where re-validation of all capabilities is expensive. + +Store client capabilities in a signed format (HMAC-signed cookie) to avoid trusting the client. When requesting new capabilities: + +1. Server verifies the signature of existing capabilities. +2. Adds the new capability to the validated set. +3. Issues a token and updates the signed storage. + +### Handling capability errors + +When a client attempts an operation without proper capabilities, Ably returns an error with code `40160`. You can catch this error and trigger reauthorization: + +```javascript +channel.attach((err) => { + if(err && err.code === 40160) { + console.log("Access denied - requesting new token with required capabilities"); + + // Update your capability requirements + channelsINeedAccessTo.push(channel.name); + + // Reauthorize with new capabilities + realtime.auth.authorize((authErr) => { + if(!authErr) { + // Retry the original operation + channel.attach(); + } + }); + } +}); +``` + +### Best practices + +- **Server validation**: Always validate that clients should have access to requested capabilities +- **Minimal privileges**: Issue tokens with only the capabilities clients actually need +- **Token expiration**: Use appropriate token TTLs to balance security and performance +- **Error handling**: Implement robust error handling for capability-related failures +- **State management**: Choose the capability management strategy that fits your application's architecture + +## WebSocket security considerations + +When using tokens with WebSocket connections, developers often have concerns about including access tokens in WebSocket connection URLs as query parameters. + +### Token placement security + +From a security perspective, the location where an access token is stored (URL query parameters, headers, or message content) provides equivalent protection when connections use TLS: + +- All connection data, including URLs and query parameters, are encrypted in transit. +- An attacker with access to inspect traffic can access tokens regardless of their location. +- TLS tunnels prevent proxies from accessing URL contents. + +### Historical security concerns + +Traditional concerns about credentials in query parameters arose from non-TLS environments and don't apply to modern WebSocket implementations: + +Addressed concerns: +- Proxies cannot access URLs when using TLS tunnels. +- Browsers don't maintain history for WebSocket connections made by pages. +- TLS prevents intermediate systems from logging connection URLs. + +Modern context: +- Most OAuth flows use `access_token` query parameters as standard practice. +- WebSocket connections default to TLS encryption. +- Client WebSocket implementations often don't support custom headers, making query parameters the practical choice. + +### Recommendations + +- Always establish WebSocket connections over TLS (WSS protocol). +- Use tokens with appropriate expiration times. +- Implement automatic token refresh for long-lived connections. +- Log and monitor token usage patterns for anomalies. + + diff --git a/src/pages/docs/channels/index.mdx b/src/pages/docs/channels/index.mdx index d326c89279..32a4307fbb 100644 --- a/src/pages/docs/channels/index.mdx +++ b/src/pages/docs/channels/index.mdx @@ -217,3 +217,15 @@ Channel [history](/docs/storage-history/history) enables clients to retrieve mes ## Presence The [presence](/docs/presence-occupancy/presence) feature enables clients to be aware of other clients that are 'present' on the channel. Client status is updated as they enter or leave the presence set. Clients can also provide an optional payload describing their status or attributes, and trigger an update event at any time. + +## Channel groups + +Ably does not support channel groups, a concept used by some other providers where channels are placed into groups to work around limitations in dynamically subscribing or unsubscribing from channels. + +**Why Ably doesn't need channel groups:** + +* With Ably client libraries, you can add or remove subscriptions to channels dynamically at any tie. +* All channels operate over a single efficient connection. +* Channel namespaces already provide grouping functionality for configuration purposes. + +Instead of channel groups, simply subscribe to the specific channels your client needs access to. The efficient multiplexing ensures optimal performance regardless of the number of channels. diff --git a/src/pages/docs/channels/options/encryption.mdx b/src/pages/docs/channels/options/encryption.mdx index 9d7fe6ce13..fc8c1aa673 100644 --- a/src/pages/docs/channels/options/encryption.mdx +++ b/src/pages/docs/channels/options/encryption.mdx @@ -14,13 +14,62 @@ redirect_from: [Transport Layer Security (TLS)](https://en.wikipedia.org/wiki/Transport_Layer_Security) is enabled by default in Ably SDKs so that data is securely sent to, and received from, Ably. However, messages are not encrypted within the Ably system. Use the encryption channel option to ensure that message payloads are opaque, that they can't be decrypted by Ably, and can only be decrypted by other clients that share your secret key. +## TLS transport security + +All Ably client libraries use TLS by default when communicating with Ably over REST or via realtime transports such as WebSockets. This provides a secure transport for communication with Ably, ensuring that messages in transit cannot be intercepted, inspected, or tampered with. + +### Disabling TLS + +If you need to disable TLS (typically to reduce communication overhead for public data streams), you can specify `tls: false` in your [client options](/docs/api/realtime-sdk#client-options) when instantiating a Realtime or REST library. + + + +### TLS restrictions + +Unencrypted communication with Ably is **disallowed** if any of the following conditions are met: + +* You attempt to use [Basic Authentication](/docs/auth/basic) and thus transmit a private API key over an unencrypted connection. You are only permitted to use unencrypted connections with [Token Authentication](/docs/auth/token) as tokens expire, limiting the impact of token interception. + +* You have specified that TLS is required in your [app settings](/docs/platform/account/app/settings). + +* A client using an unencrypted connection attempts to attach to a channel that is configured to be used with [TLS only](/docs/channels#rules). + +### TLS version support + +Ably endpoints support TLS 1.2 and TLS 1.3, providing modern, secure encryption methods that protect your data and communications from malicious attacks. + +**Automatic version negotiation:** +Ably automatically defaults to the highest TLS version supported by both the client and server. If both support TLS 1.3, it will be used by default as it provides the most secure and efficient connection. + +Benefits of TLS 1.2 and 1.3: +- Protection against vulnerabilities such as man-in-the-middle attacks. +- TLS 1.3 reduces round trips during handshake for quicker connections. +- Forward secrecy and improved encryption algorithms. +- Modern environments support these versions by default. + +#### Legacy TLS versions + +TLS 1.0 and 1.1 are deprecated and [will be sunset in June 2025](/docs/platform/deprecate/tls-v1-1). These older versions pose security risks and should be avoided. If using legacy systems, update them to support TLS 1.2 or higher. + +#### Client configuration + +Most modern clients and libraries are configured automatically to use TLS 1.2+ by default. The JavaScript library uses the TLS version supported by the browser environment, while Node.js uses the version determined by the Node.js runtime. + +### TLS vs. message encryption + +While TLS encryption ensures that messages in transit to and from Ably cannot be intercepted, inspected, or tampered with, it does not ensure that the Ably service itself is unable to inspect your messages and their content. If you want to ensure that all messages are encrypted and inaccessible to even Ably, consider using the [message-level encryption](#with-ably) feature included in the client libraries. + Setting encryption using channel options means that encryption is a feature that can be set per-channel. Apps may have both un-encrypted and encrypted channels on a single connection. -## Encryption with Ably +## Cross-platform symmetric encryption + +All officially supported Ably client libraries provide **cross-platform symmetric encryption**, ensuring that encrypted messages can be sent from one platform and successfully decrypted on any other supported platform. Ably SDKs support encryption purely as a convenience. The SDKs ensure interoperability between environments by having compatible implementations of encryption algorithms and by making common choices on things such as format, mode and padding. However, Ably intentionally does not manage the distribution of keys between clients, and end-to-end encryption is enabled without exposing keys to the Ably service at all. This has the advantage that Ably has no access to the un-encrypted contents of your messages, but also means that each app is responsible for enabling the distribution of keys to clients independently of Ably. -Encryption with Ably supports symmetric encryption only and requires each participating client to each specify the correct [`CipherParams`](/docs/api/realtime-sdk/encryption#cipher-params) secret `key` when creating a `channel` instance. Clients that do not specify a key will receive the still-encrypted message payloads, that they can subsequently decrypt offline if necessary. +Encryption with Ably supports **symmetric encryption only** and requires each participating client to each specify the correct [`CipherParams`](/docs/api/realtime-sdk/encryption#cipher-params) secret `key` when creating a `channel` instance. Clients that do not specify a key will receive the still-encrypted message payloads, that they can subsequently decrypt offline if necessary. Only the AES algorithm, with a default key length of 256 bits, and CBC mode are supported. These defaults are intended to ensure that encryption support can be provided in all target environments and platforms. diff --git a/src/pages/docs/connect/index.mdx b/src/pages/docs/connect/index.mdx index f79cf245c4..fde8e087a3 100644 --- a/src/pages/docs/connect/index.mdx +++ b/src/pages/docs/connect/index.mdx @@ -8,7 +8,19 @@ redirect_from: - /docs/realtime/versions/v0.8/connection --- -Clients establish and maintain a connection to the Ably service using the most efficient transport available, typically [WebSockets](https://ably.com/topic/websockets). Ably SDKs operate and multiplex all [channel](/docs/channels) traffic over that connection. This maximizes throughput, minimizes bandwidth consumption, and reduces power usage. Once connected, clients can monitor and manage their [connection state](/docs/connect/states). +Clients establish and maintain a connection to the Ably service using the most efficient transport available, typically [WebSockets](https://ably.com/topic/websockets). + +## Connection multiplexing + +Ably SDKs operate and multiplex all [channel](/docs/channels) traffic over a single connection. This means you can publish and subscribe to messages on any number of channels simultaneously using just one transport connection. This approach: + +* Maximizes throughput by efficiently utilizing the available connection. +* Minimizes bandwidth consumption by avoiding multiple connection overhead. +* Reduces power usage by maintaining fewer active connections. + +All Ably client libraries support multiplexing by default when using the realtime interface. You can dynamically subscribe and unsubscribe from channels at any time without needing to establish new connections. + +Once connected, clients can monitor and manage their [connection state](/docs/connect/states).