Skip to content

OAuth Scope Sharing Across Slack Integrations: Security Implications for AI Applications #1606

@yu-iskw

Description

@yu-iskw

Summary

I've encountered some unexpected behavior with OAuth scope management in the Composio Slack integration that affects usability and creates confusion around permissions. The main issues are:

  1. OAuth scopes appear to be shared across different Slack integrations in the same workspace
  2. The actual OAuth scopes granted are much broader than what's specified in the integration settings, though actual granted scopes at the user level can be narrowed down.

Detailed Description

Issue 1: OAuth Scopes Shared Across Integrations

What I Expected: Each Slack integration would have independent OAuth connections with their own specified scopes.

What Actually Happens: When I create multiple Slack integrations for the same workspace, they seem to share OAuth permissions. For example:

  • Created Integration A with basic scopes (no search:read)
  • Integration A correctly failed when trying to search messages
  • Created Integration B with additional search:read scope
  • Integration B can search messages as expected
  • Unexpectedly: Integration A can now also search messages, even though its configuration doesn't include search:read

Issue 2: Broader Scopes Than Expected

Important Clarification: After reviewing the Slack API scopes documentation, it's clear that Slack distinguishes between different types of scopes:

  • User scopes: OAuth permissions for actions on behalf of a user
  • Bot scopes: Permissions for the bot/app itself
  • App-level scopes: Application-level permissions

What I Specified (Integration A user scopes):

  • channels:history
  • chat:write
  • team:read
  • channels:read
  • users:read
  • reminders:write
  • reactions:read

What Was Actually Granted (visible in Slack workspace):

The Composio Slack app appears to have been granted extensive permissions at the app/bot level, including:

  • All the specified user scopes above, plus
  • Many additional bot and admin scopes like:
    • admin (full workspace administration)
    • admin.analytics:read
    • admin.apps:read/write
    • admin.users:read/write
    • chat:write (Bot scope)
    • channels:manage (Bot scope)
    • files:write (Bot scope)
    • And many others (40+ total scopes)

The Issue: There seems to be confusion between:

  1. User OAuth scopes (what should be specified per integration for user actions)
  2. App/Bot scopes (what the Composio app itself has been granted in the workspace)

Ideally, Composio integrations should specify both:

  • App-level scopes: What the Composio app needs to function
  • User OAuth scopes: What specific permissions each integration should request for user actions

Reproduction Steps

  1. Create a new Slack integration (Integration A) with default scopes
  2. Note that search:read is not included in the specified scopes
  3. Test message search functionality - it fails with "missing_scope" error
  4. Create another Slack integration (Integration B) that includes search:read
  5. Test message search on Integration B - it works
  6. Test message search on Integration A again - it now works unexpectedly

API Response Example

When Integration A initially tried to search (before Integration B was created):

{
  "data": {
    "error": "missing_scope",
    "needed": "search:read",
    "ok": false,
    "provided": "identify,channels:history,channels:read,reactions:read,team:read,users:read,chat:write,reminders:wr..."
  },
  "successful": true,
  "error": null,
  "log_id": "log__u4duDv1HOIi"
}

Potential Explanation

It seems like the Slack OAuth connection might be tied to the workspace/user combination rather than individual integrations. This would explain why:

  • Permissions are shared across integrations
  • The OAuth token has the union of all requested scopes
  • Changes in one integration affect others

Architecture Diagrams

Expected Behavior (Isolated OAuth Connections)

graph TD
    SlackUser["Slack User"] --> Integration1["Integration A<br/>(Basic Scopes)"]
    SlackUser --> Integration2["Integration B<br/>(Basic + search:read)"]

    Integration1 --> OAuth1["OAuth Connection A<br/>(Basic Scopes Only)"]
    Integration2 --> OAuth2["OAuth Connection B<br/>(Basic + search:read)"]

    OAuth1 --> SlackApp1["Composio Slack App<br/>(Limited Permissions)"]
    OAuth2 --> SlackApp2["Composio Slack App<br/>(Extended Permissions)"]

    subgraph ComposioProjects["Composio Platform"]
        Integration1
        Integration2
    end

    subgraph SlackWorkspace["Slack Workspace"]
        SlackUser
        SlackApp1
        SlackApp2
    end

    subgraph OAuthLayer["OAuth Layer (Expected)"]
        OAuth1
        OAuth2
    end

    style OAuthLayer fill:#e8f5e8
    style OAuth1 fill:#c8e6c9
    style OAuth2 fill:#c8e6c9
Loading

Actual Behavior (Shared OAuth Connection)

graph TD
    SlackUser["Slack User"] --> Integration1["Integration A<br/>(Basic Scopes)"]
    SlackUser --> Integration2["Integration B<br/>(Basic + search:read)"]

    Integration1 --> SharedOAuth["Single OAuth Connection<br/>(Union of All Scopes<br/>+ Additional Admin Scopes)"]
    Integration2 --> SharedOAuth

    SharedOAuth --> SlackApp["Composio Slack App<br/>(Cumulative Permissions)"]

    subgraph ComposioProjects["Composio Platform"]
        Integration1
        Integration2
    end

    subgraph SlackWorkspace["Slack Workspace"]
        SlackUser
        SlackApp
    end

    subgraph OAuthLayer["OAuth Layer (Actual)"]
        SharedOAuth
    end

    style OAuthLayer fill:#ffebee
    style SharedOAuth fill:#ffcdd2
Loading

Impact on Users

Usability Issues:

  • Confusing behavior when scopes seem to change unexpectedly
  • Difficulty planning integration permissions
  • Can't fine-tune permissions per integration

Workflow Issues:

  • Can't modify scopes after initial setup
  • May need to recreate integrations to change permissions
  • Unclear what permissions are actually active

Practical Application Impact

This OAuth scope sharing behavior can cause significant confusion and unexpected behavior in applications built on top of Composio integrations:

Example Scenario: Web Application Permissions

Consider two web applications using different Slack integrations:

Web App A uses Slack Integration A (basic scopes only):

  • Integration A is configured with basic scopes: channels:read, chat:write, users:read
  • Web App A is designed to only allow basic messaging functionality
  • Developers expect that Web App A users cannot search messages or access admin functions

Web App B uses Slack Integration B (extended scopes):

  • Integration B includes additional scopes like search:read, admin permissions
  • Web App B is designed for advanced workspace management

The Problem

Due to the scope management issues:

  1. Scope Level Confusion: It's unclear whether integration scopes refer to user OAuth scopes or app-level capabilities
  2. Unexpected Capabilities: Users of Web App A can technically perform actions that Integration A's user scope configuration suggests they shouldn't be able to do (like searching messages)
  3. Security Assumptions Broken: Web App A developers assume certain user actions are impossible based on their integration's specified user scopes, but they're actually available through shared OAuth connections or app-level permissions
  4. Inconsistent Behavior: The same user might have different capabilities in Web App A depending on whether other integrations exist in the workspace

Developer Confusion

Technical Mitigation Available: Developers can technically avoid this issue by:

  • Configuring allowed actions on the Composio side
  • Carefully selecting only intended tools in web applications
  • Implementing strict tool filtering per integration

The Problem: This approach is cumbersome and error-prone:

  • Configuration Complexity: Requires manual mapping of OAuth scopes to allowed tools
  • Maintenance Overhead: Must be kept in sync as scopes and tools evolve
  • Policy Enforcement: No built-in mechanism to prevent misconfigurations
  • Human Error Risk: Easy to accidentally expose unintended functionality

Expected Behavior: OAuth scope boundaries should automatically enforce tool availability:

Business Impact

  • Compliance Issues: Applications may inadvertently access data beyond their intended scope
  • User Confusion: Features may appear/disappear based on other integrations in the workspace
  • Development Overhead: Extra validation logic needed to enforce intended scope limitations
  • Trust Issues: Difficulty explaining to users why permission boundaries seem inconsistent

Critical AI Security Scenario

This OAuth scope sharing issue becomes particularly serious when AI-powered applications are involved:

High-Risk Example: AI Agent Privilege Escalation

Consider a company with two AI-powered applications:

Web App A - AI Admin Assistant:

  • Target users: Slack workspace administrators
  • Purpose: AI agent helps admins manage the workspace
  • Required scopes: Broad administrative permissions including:
    • admin (full workspace administration)
    • admin.users:write (manage user accounts)
    • admin.channels:write (manage all channels)
    • admin.apps:write (manage workspace apps)
    • channels:manage (create/modify channels)
    • usergroups:write (manage user groups)

Web App B - AI Search Assistant:

  • Target users: Regular employees
  • Purpose: AI agent helps employees find information in Slack
  • Intended scopes: Limited search permissions:
    • search:read (search workspace content)
    • channels:read (view channel information)
    • users:read (view user information)

The Critical Problem

When a user who is both a Slack admin and regular employee uses both applications:

  1. Scope Escalation: Web App B's AI agent gains access to admin-level scopes from Web App A
  2. AI Misuse Risk: The search AI agent could potentially:
    • Delete or modify channels (admin.channels:write)
    • Remove users from the workspace (admin.users:write)
    • Install or remove workspace apps (admin.apps:write)
    • Access sensitive administrative data
  3. Unintended Actions: The AI agent might use these powerful scopes during normal search operations, especially if:
    • The AI misinterprets user requests
    • There are prompt injection attacks
    • The AI model hallucinates administrative actions

Real Security Risk

According to the Slack scopes documentation, admin scopes provide extremely powerful capabilities:

  • admin: Full workspace administration
  • admin.users:write: Modify account information
  • admin.apps:write: Manage apps in a workspace
  • admin.teams:write: Make changes to a workspace

Critical Issue: If Web App B's AI agent has access to these scopes due to OAuth sharing:

Mitigation Challenges

Available Technical Approaches:

  • Configure allowed actions per integration on Composio platform
  • Implement strict tool filtering and validation in AI applications
  • Manual mapping between OAuth scopes and available tools
  • Complex policy enforcement layers

Why These Approaches Are Insufficient:

  • Configuration Burden: Developers must manually maintain scope-to-tool mappings
  • Policy Gaps: No automatic enforcement of scope boundaries at the OAuth level
  • Human Error: Easy to misconfigure tool availability
  • Maintenance Complexity: Tools and scopes evolve independently, creating sync issues

The Risk: Even with careful configuration, the underlying OAuth permissions are available, creating a potential attack surface for:

  • AI model errors or hallucinations
  • Prompt injection attacks
  • Configuration mistakes
  • Future AI model updates that change behavior

The Uncontrollable AI Factor

Critical Insight: While developers can consciously or unconsciously allow/disallow tool calling, AI agents present a fundamentally different and more dangerous risk profile:

Autonomous Decision Making:

  • AI agents can make rapid, autonomous decisions without human oversight
  • Unlike human developers who act deliberately, AI behavior can be emergent and unpredictable
  • AI models can chain together multiple tool calls in unexpected ways

Examples of Uncontrollable AI Actions:

  1. Context Confusion: AI agent confuses "search for deleted messages" with "delete messages"
  2. Scope Creep: AI agent decides to "clean up workspace" using admin tools during a search operation
  3. Hallucinated Authority: AI agent assumes it has permission to make "helpful" administrative changes
  4. Chain Reactions: AI agent triggers one admin action that leads to cascading unintended consequences

Why This Is More Dangerous Than Developer Error:

  • Speed: AI can execute hundreds of actions per minute
  • Scale: AI doesn't understand the scope of damage from admin actions
  • Persistence: AI might repeatedly attempt harmful actions until stopped
  • Hidden Actions: AI behavior may not be immediately visible to users
  • Non-Deterministic: Same inputs might produce different AI behaviors over time

Real-World Risk Scenario:
An employee asks the "search AI": "Can you help clean up our workspace by finding old unused channels?"

Without proper scope isolation, the AI might:

  1. Search for old channels ✓ (intended)
  2. Decide to "helpfully" delete them ✗ (unintended admin action)
  3. Remove "inactive" users from those channels ✗ (cascading admin action)
  4. Archive related projects ✗ (AI hallucination)

The Core Problem: Even with perfect tool filtering by developers, the underlying OAuth permissions create a persistent attack surface that AI models can potentially exploit through:

  • Emergent behavior patterns
  • Model updates changing decision-making
  • Novel prompt combinations not anticipated by developers
  • AI "creativity" in problem-solving that bypasses intended restrictions

Suggestions

  1. Clarify Scope Types: Distinguish between app-level scopes and user OAuth scopes in the integration configuration
  2. Separate Scope Management: Allow configuration of both:
    • App-level scopes: What the Composio app needs (set once per workspace)
    • User OAuth scopes: What each integration can do on behalf of users (set per integration)
  3. Scope Management UI: Provide a way to view and modify actual OAuth scopes at both levels
  4. Integration Isolation: Consider whether each integration should have its own user OAuth connection
  5. Scope Validation: Show users the actual granted scopes vs. specified scopes, clearly labeled by scope type
  6. Documentation: Update documentation to explain the difference between Slack's app/bot scopes and user OAuth scopes, referencing the official Slack scopes documentation

Additional Context

This behavior might be intentional for simplicity, but it creates some confusion about how permissions work. It would be helpful to have clearer documentation about:

  • How OAuth connections are managed across multiple integrations
  • What the relationship is between specified scopes and actual granted scopes
  • Whether the broader scope permissions are necessary for the platform to function

Potential Impact on Other Integrations

Important Note: This OAuth scope management behavior might not be limited to Slack integrations. Similar issues could potentially affect other OAuth-based integrations in the Composio platform, such as:

  • GitHub: Where repository access, organization permissions, and user scopes might be shared across multiple GitHub integrations
  • Google Workspace: Where document access, calendar permissions, and admin scopes could exhibit similar sharing behavior
  • Microsoft 365: Where Teams, SharePoint, and Outlook permissions might be cumulative rather than isolated
  • Other OAuth integrations: Any integration using OAuth authentication could potentially have the same scope sharing architecture

Recommendation: It might be worth reviewing the OAuth connection management across all integrations to ensure this behavior is consistent with user expectations and properly documented across the platform.

Thanks for looking into this! Let me know if you need any additional information or testing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions