Authenticate RedisVL MCP#

This guide explains how the RedisVL MCP server authenticates clients on its HTTP transports and how it gates read vs write access. It also draws the boundary between what RedisVL enforces and what belongs in a gateway or policy layer.

Note

Authentication applies only to the HTTP transports (streamable-http, sse). The stdio transport is a local subprocess with no network surface and is never authenticated.

What RedisVL Enforces#

RedisVL validates a bearer JWT that an existing identity provider (IdP) issued. It does not run an OAuth authorization server and does not issue tokens.

On each request it checks:

  • Signature, against a JWKS endpoint or a static public key.

  • Issuer (iss), so only tokens from your IdP are accepted.

  • Audience (aud), so a token minted for a different service cannot be replayed against this server (RFC 8707).

  • Expiration: a present exp in the past is rejected, and tokens are required to carry exp and iat (configurable via required_claims), so a token with no expiration, which would never expire, is rejected.

  • Required scopes to connect, and (optionally) a read scope to call search-records and a write scope to call upsert-records.

Important

This is coarse authorization: it decides whether a caller may connect and whether it may read or write. It does not map token claims to a Redis ACL user, a per-tenant index, or query filters. See The Authorization Boundary.

OAuth: Which Part RedisVL Handles#

In OAuth terms, RedisVL MCP is a resource server: it validates access tokens that your identity provider issued. It does not run an OAuth login flow and does not issue tokens.

flowchart LR Client -->|1 - OAuth login flow| IdP[Identity Provider] IdP -->|2 - issues JWT access token| Client Client -->|3 - Bearer JWT| MCP[RedisVL MCP] MCP -->|validates token| Redis[(Redis)]

Steps 1 and 2 (obtaining the token) are handled by your client and IdP. RedisVL only performs the validation in step 3. As a result:

  • It works with any OAuth 2.0 / OIDC provider (for example Auth0, Okta, Azure AD / Entra, Cognito, Keycloak): point jwks_uri at the provider and validate its tokens.

  • RedisVL does not broker interactive “log in with…” flows and does not mint tokens.

You would only need more than token validation when you want the server itself to drive an interactive browser login (an OAuth proxy), or to act as its own authorization server that issues tokens. Both are out of scope today. If interactive login is ever needed, a single generic oauth-proxy option can be added behind the auth.type switch. For enterprise and agent deployments where the caller already holds a token, JWT validation is sufficient.

Request Flow#

sequenceDiagram actor User participant IdP as Identity Provider participant MCP as RedisVL MCP Server participant Redis User->>IdP: Authenticate IdP-->>User: Signed JWT (iss, aud, scopes/roles) User->>MCP: MCP request + Bearer JWT MCP->>MCP: Validate signature (JWKS / public key) MCP->>MCP: Check issuer + audience alt token invalid / wrong audience / missing connect scope MCP-->>User: 401 Unauthorized else token valid MCP->>MCP: Gate tool by read / write scope alt scope present MCP->>Redis: Search or upsert (single configured ACL user) Redis-->>MCP: Results MCP-->>User: Tool result else scope missing MCP-->>User: Forbidden end end

Configure JWT Authentication#

Add a server.auth block to your MCP config. Secrets can be injected with ${ENV} substitution.

server:
  redis_url: ${REDIS_URL:-redis://localhost:6379}
  auth:
    type: jwt
    jwks_uri: ${MCP_JWKS_URI}          # or set public_key for a static key
    issuer: ${MCP_ISSUER}
    audience: api://redisvl-mcp
    required_scopes: [kb.read]         # required to connect
    required_claims: [exp, iat]        # claims every token must carry (default)
    read_scope: kb.search.read         # required for search-records
    write_scope: kb.search.write       # required for upsert-records

indexes:
  knowledge:
    redis_name: docs_index
    search:
      type: fulltext
    runtime:
      text_field_name: content

Every field is also settable through REDISVL_MCP_AUTH_* environment variables, which take precedence over the YAML block.

Choosing the Authorization Claim#

Different identity providers carry authorization in different claims. The default JWT scope claim is scp (or scope). Some enterprise providers carry authorization in a roles claim instead, which does not appear in the standard scope set.

flowchart TD A[Validated JWT claims] --> B{authorization_claim} B -->|scp / scope| C["access.scopes<br/>e.g. kb.read"] B -->|roles| D["access.claims.roles<br/>e.g. kb.search.read"] C --> E[Check read_scope / write_scope] D --> E E -->|present| F[Allow tool] E -->|absent| G[Deny tool]

Set the claim that holds your authorization values so read and write gating reads the right place:

server:
  auth:
    type: jwt
    # ...
    authorization_claim: roles   # default: scp
    read_scope: kb.search.read
    write_scope: kb.search.write

A token like the following would then pass the read gate, because kb.search.read is present in roles:

{
  "iss":   "https://your-idp.example/{tenant}/v2.0",
  "aud":   "api://redisvl-mcp",
  "sub":   "nitin",
  "roles": ["kb.search.read"],
  "scp":   "kb.read"
}

The Authorization Boundary#

RedisVL MCP authenticates the caller and gates read vs write. It does not translate token claims (such as a tenant id or role) into a specific Redis ACL user, a per-tenant index, or injected query filters. The server holds one Redis connection for one index, established at startup.

Fine-grained, per-tenant data isolation belongs in a gateway or policy layer in front of the MCP server, which validates the token, looks up a binding of claim to Redis identity, and injects credentials and filters.

flowchart LR subgraph Gateway["Gateway / policy layer (out of scope for RedisVL)"] T[Validate token] --> M["Map claims to<br/>Redis user + index + filters"] end subgraph RedisVL["RedisVL MCP (this guide)"] A[Validate JWT] --> S[Gate read / write by scope] end Client --> Gateway --> RedisVL --> Redis[(Redis)]

Use RedisVL’s JWT validation for authentication and coarse read/write authorization. Layer a gateway on top when you need per-tenant Redis ACL enforcement.

See Also#