CrewAI Tutorial (Python): adding authentication for advanced developers

By Cyprian AaronsUpdated 2026-04-21
crewaiadding-authentication-for-advanced-developerspython

This tutorial shows you how to add authentication to a CrewAI-based Python workflow so your agents can call protected APIs, gate sensitive tools, and enforce per-user access. You need this when your crew is doing more than local reasoning and starts touching real systems like internal services, customer data, or paid third-party APIs.

What You'll Need

  • Python 3.10+
  • crewai
  • crewai-tools
  • requests
  • An API key or bearer token for the protected service you want to call
  • A .env file for secrets
  • Basic familiarity with CrewAI agents, tasks, and tools

Install the packages:

pip install crewai crewai-tools requests python-dotenv

Step-by-Step

  1. Start by loading credentials from environment variables instead of hardcoding them. For production systems, this is the minimum bar before an agent touches any authenticated endpoint.
import os
from dotenv import load_dotenv

load_dotenv()

API_BASE_URL = os.getenv("API_BASE_URL", "https://api.example.com")
API_TOKEN = os.getenv("API_TOKEN")

if not API_TOKEN:
    raise ValueError("API_TOKEN is required")
  1. Create a reusable authenticated tool that attaches the token on every request. This keeps auth logic out of your agent prompts and makes the tool safe to reuse across multiple crews.
import requests
from crewai_tools import tool

@tool("get_account_profile")
def get_account_profile(account_id: str) -> str:
    """Fetch an account profile from a protected API."""
    headers = {"Authorization": f"Bearer {API_TOKEN}"}
    url = f"{API_BASE_URL}/accounts/{account_id}"
    response = requests.get(url, headers=headers, timeout=15)
    response.raise_for_status()
    return response.text
  1. Wire the authenticated tool into a CrewAI agent and keep the prompt focused on behavior, not secrets. The agent should know what it can do, but never see the token itself.
from crewai import Agent

auth_agent = Agent(
    role="Authenticated Support Agent",
    goal="Retrieve account data only when authorized and summarize it accurately",
    backstory="You work with protected customer systems and must use approved tools.",
    tools=[get_account_profile],
    verbose=True,
)
  1. Add a task that forces the agent to use the authenticated tool instead of hallucinating data. This is where you define the contract: what input it gets and what output you expect.
from crewai import Task

account_task = Task(
    description=(
        "Use the get_account_profile tool to fetch account 12345 "
        "and return a concise summary of the profile."
    ),
    expected_output="A short summary of the authenticated account profile.",
    agent=auth_agent,
)
  1. Put everything into a crew and run it. At this point, your agent will only be able to access protected data through the authenticated request path you defined.
from crewai import Crew, Process

crew = Crew(
    agents=[auth_agent],
    tasks=[account_task],
    process=Process.sequential,
)

if __name__ == "__main__":
    result = crew.kickoff()
    print(result)
  1. If your API uses per-user auth instead of one shared service token, pass user context into the tool explicitly. That gives you room for audit trails, tenant isolation, and scoped permissions without changing the agent layer.
@tool("get_user_orders")
def get_user_orders(user_id: str) -> str:
    """Fetch orders for a specific user using a scoped bearer token."""
    token = os.getenv(f"USER_TOKEN_{user_id}")
    if not token:
        raise ValueError(f"Missing token for user {user_id}")

    headers = {"Authorization": f"Bearer {token}"}
    url = f"{API_BASE_URL}/users/{user_id}/orders"
    response = requests.get(url, headers=headers, timeout=15)
    response.raise_for_status()
    return response.text

Testing It

Run the script with a valid API_TOKEN in your environment and confirm you get a real response from the protected endpoint. If authentication is wrong, requests.raise_for_status() should fail fast with a 401 or 403 instead of letting the agent continue with bad data.

Test one happy path and one failure path. For example, set an invalid token once and verify that your tool raises an exception before CrewAI tries to summarize anything.

If you're using multiple users or tenants, verify that each user gets only their own data by checking responses against known records. Also inspect logs to make sure tokens are never printed by the agent or task output.

Next Steps

  • Add OAuth2 client credential flow instead of static bearer tokens
  • Wrap tools with policy checks for role-based access control
  • Add request signing and audit logging for regulated environments

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides