Skip to content

Integrate Splunk MCP with MoP: mirror users, SAML role inheritance, and Splunk token mint#21

Merged
yosrixp merged 1 commit intomainfrom
splunk
Apr 10, 2026
Merged

Integrate Splunk MCP with MoP: mirror users, SAML role inheritance, and Splunk token mint#21
yosrixp merged 1 commit intomainfrom
splunk

Conversation

@yosrixp
Copy link
Copy Markdown
Collaborator

@yosrixp yosrixp commented Apr 10, 2026

PR description

Summary

This work integrates the Splunk MCP surface with the MCP OAuth Proxy (MoP) so end users authenticate with Okta while Splunk access uses a dedicated native mirror account mcp.<short_id>. MoP calls the Splunk management API (admin bearer from existing credentials) to ensure that mirror user exists, reconcile roles, and mint a short-lived Splunk bearer token for the MCP client. Resource mapping and as: splunk follow the same patterns as other non-JAG providers (e.g. Glean/GCP).

Architecture (high level)

flowchart LR
  subgraph Client_side
    MCP_Client[MCP client]
  end
  subgraph MoP
    Token_EP[MoP token endpoint]
    Authz[AuthorizerService]
    SplunkEx[TokenExchangeServiceSplunkImpl]
  end
  subgraph Splunk
    Mgmt[Splunk management API :8089]
    SAML_User[Splunk user short_id SAML]
    Mirror_User[Native user mcp.short_id]
    MCP_Srv[Splunk MCP server]
  end

  MCP_Client -->|OAuth / token grant + resource URI| Token_EP
  Token_EP --> Authz
  Authz -->|TokenExchangeDO + Okta id_token| SplunkEx
  SplunkEx -->|Admin REST: lookup / users / mint| Mgmt
  Mgmt --- SAML_User
  Mgmt --- Mirror_User
  MCP_Client -->|Splunk access_token| MCP_Srv
Loading

Interaction idea: The client never receives a token minted as the SAML username. MoP always targets mcp.<short_id> for create/update and token mint, using short_id (or configured username claim) from the Okta id_token to correlate with the real Splunk identity.


Mirror user mcp.<short_id> and roles

Baseline (default roles) come from config allowed-roles (e.g. yahoo_user, mcp_user). These are always part of the mirror user’s role set.

Provisioning / reconciliation flow

flowchart TD
  Start([Token exchange: Splunk resource]) --> ReadClaim[Read username from id_token e.g. short_id]
  ReadClaim --> LookupReal[GET Splunk user short_id]
  LookupReal --> LookupMirror[GET Splunk user mcp.short_id]
  LookupReal --> SAML{Splunk user short_id exists?}
  SAML -->|Yes| RolesUnion["desired roles = allowed-roles ∪ all roles on short_id"]
  SAML -->|No| RolesBaseline["desired roles = allowed-roles only"]
  RolesUnion --> Compare{Mirror exists and roles match desired?}
  RolesBaseline --> Compare
  Compare -->|No mirror| Create[POST create mcp.short_id with desired roles]
  Compare -->|Mirror exists, drift| Update[POST update roles on mcp.short_id]
  Compare -->|Match| MintOnly[Skip user/role writes]
  Create --> Mint[Mint Splunk bearer for mcp.short_id]
  Update --> Mint
  MintOnly --> Mint
  Mint --> Return([Return access_token to client])
Loading
Scenario Splunk user <short_id> (SAML) Mirror mcp.<short_id> roles
SAML account present Found All roles on <short_id> plus allowed-roles (defaults)
SAML account absent Not found allowed-roles only

Tokens are minted for mcp.<short_id>, not for the SAML name, which keeps management and MCP access on a controlled native principal.


Configuration (conceptual)

  • Splunk management base URL via remote-servers / resource mapping (full URL per env).
  • server.token-exchange.splunk: mirror prefix, allowed-roles, token audience, TTL, admin token secret key (same K8s secret pattern as the plan).
  • MCP Gateway resource URIs (stage/prod) drive routing to this exchange path per existing resource-mapping.

…nd Splunk token mint

Signed-off-by: yosrixp <yosrixp@yahoo.com>
@yosrixp yosrixp merged commit f809c4d into main Apr 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants