|
| 1 | +--- |
| 2 | +title: Cisco Duo |
| 3 | +description: Authorize tools and agents with Cisco Duo (OIDC) on behalf of a user |
| 4 | +--- |
| 5 | + |
| 6 | +import { Tabs, Callout, Steps } from "nextra/components"; |
| 7 | + |
| 8 | +# Cisco Duo |
| 9 | + |
| 10 | +The Cisco Duo auth provider lets tools and agents authorize with Cisco Duo and call your Duo-protected APIs, apps, and systems on behalf of a user. Duo Single Sign-On acts as an OpenID Connect (OIDC) provider, so Arcade runs the standard authorization code flow, including Duo's multi-factor (Duo Push) prompt, and hands your tool a token. |
| 11 | + |
| 12 | +<Callout> |
| 13 | + **Cisco Duo is the central place for your access policies:** identities, |
| 14 | + groups, scopes, and multi-factor requirements all live in Duo. **Arcade |
| 15 | + enforces those policies in real time, on every tool call.** Each tool requests |
| 16 | + the scopes it needs, Duo decides what to grant for each user or group, and an |
| 17 | + agent can only ever act within the access Duo has authorized. Change a policy |
| 18 | + in Duo and it takes effect on the next call, with no changes to your tools or |
| 19 | + agents. |
| 20 | +</Callout> |
| 21 | + |
| 22 | +<Callout> |
| 23 | + Cisco Duo is configured as a custom OAuth 2.0 provider. Duo's OAuth/OIDC |
| 24 | + endpoints are unique to your Duo account, so you bring your own Duo application |
| 25 | + credentials and endpoints. The generic [OAuth 2.0 |
| 26 | + provider](/references/auth-providers/oauth2) page is the underlying |
| 27 | + configuration reference. |
| 28 | +</Callout> |
| 29 | + |
| 30 | +## What's documented here |
| 31 | + |
| 32 | +This page describes how to configure Cisco Duo auth with Arcade, and use it from: |
| 33 | + |
| 34 | +- An [agentic client](#use-cisco-duo-from-an-agentic-client) (Claude Code, Claude Desktop, Cursor, or your own agent) connected to an Arcade MCP gateway |
| 35 | +- Your [custom tools](#create-your-own-duo-authorized-tools) that call the APIs, apps, and systems protected by Cisco Duo |
| 36 | + |
| 37 | +## Create a Cisco Duo OIDC application |
| 38 | + |
| 39 | +<Callout type="info"> |
| 40 | + When using your own app credentials, make sure you configure your project to |
| 41 | + use a [custom user |
| 42 | + verifier](/guides/user-facing-agents/secure-auth-production#build-a-custom-user-verifier). |
| 43 | + Without this, your end-users will not be able to use your app or agent in |
| 44 | + production. |
| 45 | +</Callout> |
| 46 | + |
| 47 | +In the [Duo Admin Panel](https://admin.duosecurity.com): |
| 48 | + |
| 49 | +1. Go to **Applications → Protect an Application**. |
| 50 | +2. Search for **OIDC** and select the Single Sign-On application that makes Duo the OpenID Provider, labeled **"OAuth 2.1 / OIDC - Single Sign-On"** or **"Generic OIDC Relying Party"**, depending on your Duo version. Click **Protect**. |
| 51 | +3. On the **General** tab: |
| 52 | + - Enable the **Authorization Code** grant type. Also enable **Refresh Token** if you want Arcade to refresh tokens silently. |
| 53 | + - Leave **Sign-In Redirect URLs** empty for now. You'll add the Arcade-generated redirect URL after you create the provider in Arcade. |
| 54 | +4. On the **Scopes** tab, enable `openid`, `profile`, and `email`. Add any custom scopes your API requires (for example, `crm.contacts.read`). Duo requires each custom scope to map at least one claim. |
| 55 | +5. On the **Clients** tab, add `openid`, `profile`, `email`, and any custom scopes to the client's **Confidential client scopes** so the client is allowed to request them. |
| 56 | +6. On the **Access Policy** tab, under **Scope Authorization**, grant the scopes to the users or groups who should have them. Duo becomes the authorization source of truth: revoking a scope here blocks the tools that require it. |
| 57 | +7. Set **User access** to the users or groups who may sign in, and confirm the application's policy **requires two-factor authentication** so the Duo Push prompt is shown. |
| 58 | +8. Click **Save**. |
| 59 | + |
| 60 | +The **Access Policy** tab is where you grant scopes to users and groups, which decides who can run which tools: |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | +From the application's **Metadata** tab, copy the **Client ID**, **Client Secret**, and the **Issuer**. The Issuer looks like `https://sso-<tenant>.sso.duosecurity.com/oauth2/<app_id>`. You'll need these values in the next steps. |
| 65 | + |
| 66 | +## Get your Duo issuer URL |
| 67 | + |
| 68 | +All of your Duo OAuth/OIDC endpoints live under your account's per-tenant **Issuer** base URL, shown on the application's **Metadata** tab: |
| 69 | + |
| 70 | +```text |
| 71 | +https://sso-<tenant>.sso.duosecurity.com/oauth2/<app_id> |
| 72 | +``` |
| 73 | + |
| 74 | +The endpoints are derived from it: |
| 75 | + |
| 76 | +- Authorization: `<issuer>/authorize` |
| 77 | +- Token: `<issuer>/token` |
| 78 | +- UserInfo: `<issuer>/userinfo` |
| 79 | + |
| 80 | +Copy the exact Issuer from the Metadata tab rather than building it by hand. The `<tenant>` and `<app_id>` segments are specific to your Duo account and application. |
| 81 | + |
| 82 | +## Configuring Cisco Duo auth |
| 83 | + |
| 84 | +<Tabs items={["Dashboard GUI"]}> |
| 85 | +<Tabs.Tab> |
| 86 | + |
| 87 | +### Configure Cisco Duo auth using the Arcade Dashboard |
| 88 | + |
| 89 | +<Steps> |
| 90 | + |
| 91 | +#### Access the Arcade Dashboard |
| 92 | + |
| 93 | +Go to the [Arcade Dashboard](https://api.arcade.dev/dashboard) and log in with your Arcade account credentials. |
| 94 | + |
| 95 | +#### Navigate to the OAuth providers page |
| 96 | + |
| 97 | +- Under the **Connections** section of the Arcade Dashboard left-side menu, click **Connected Apps**. |
| 98 | +- Click **Add OAuth Provider** in the top right corner. |
| 99 | +- Select the **Custom Provider** tab at the top. |
| 100 | + |
| 101 | +#### Enter the provider details |
| 102 | + |
| 103 | +- Enter `cisco-duo-oidc` as the **ID** for your provider. It can be any unique string you reference from your tools and app code. |
| 104 | +- Optionally enter a **Description**. |
| 105 | +- Enter your Duo **Client ID** and **Client Secret** from the application's Metadata tab. |
| 106 | +- Note the **Redirect URL** generated by Arcade. You'll add it to your Duo application in a later step. |
| 107 | + |
| 108 | +#### Configure the auth endpoints |
| 109 | + |
| 110 | +<Callout type="info"> |
| 111 | + Replace `<issuer>` with your [Duo issuer URL](#get-your-duo-issuer-url), for |
| 112 | + example `https://sso-abcd1234.sso.duosecurity.com/oauth2/DI0123456789ABCDEF`. |
| 113 | +</Callout> |
| 114 | + |
| 115 | +- **Authorization Endpoint**: `<issuer>/authorize` |
| 116 | +- **Token Endpoint**: `<issuer>/token` |
| 117 | +- Under **PKCE Settings**, check **Enable PKCE** and select method **S256**. Duo is OAuth 2.1 and requires PKCE. |
| 118 | +- Under **Authorization Settings**, set the `scope` parameter to `{{scopes}} {{existing_scopes}}`. Request `openid profile email` plus any custom scopes your API needs. |
| 119 | +- (Optional) Under **User Info Settings**, set the **User Info Endpoint** to `<issuer>/userinfo`. |
| 120 | + |
| 121 | +Your provider configuration should look like this: |
| 122 | + |
| 123 | + |
| 124 | + |
| 125 | +#### Add the redirect URL to Duo |
| 126 | + |
| 127 | +Copy the **Redirect URL** that Arcade generated and add it to your Duo application's **Sign-In Redirect URLs** (on the application's **General** tab), then save the Duo application. |
| 128 | + |
| 129 | +#### Create the provider |
| 130 | + |
| 131 | +Click the **Create** button. Cisco Duo is now ready to be used in the Arcade Engine. |
| 132 | + |
| 133 | +</Steps> |
| 134 | +</Tabs.Tab> |
| 135 | +</Tabs> |
| 136 | + |
| 137 | +## Use Cisco Duo from an agentic client |
| 138 | + |
| 139 | +The most common way to use Cisco Duo with Arcade is to put a Duo-protected system (an API, database, internal app, or other enterprise system) behind an MCP server, make it available in Arcade, and connect any agentic client (such as Claude Code, Claude Desktop, Cursor, or your own agent) to your Arcade MCP gateway. Each tool declares the Cisco Duo scopes it needs, and Arcade runs the Duo sign-in (including Duo Push) the first time a user calls it. The access token never reaches the model or the client. |
| 140 | + |
| 141 | +<Steps> |
| 142 | + |
| 143 | +### Deploy a Duo-protected MCP server to Arcade |
| 144 | + |
| 145 | +Build an MCP server whose tools require Cisco Duo auth (see [Create your own Duo-authorized tools](#create-your-own-duo-authorized-tools)), then make it available in Arcade by either: |
| 146 | + |
| 147 | +- Deploying a [custom MCP server](/guides/create-tools/tool-basics/build-mcp-server) to Arcade with [`arcade deploy`](/guides/deployment-hosting/arcade-deploy), or |
| 148 | +- Adding an existing remote MCP server to your Arcade project. |
| 149 | + |
| 150 | +Once deployed, your server and its tools appear in the Arcade Dashboard under **Servers**. Each tool shows the Cisco Duo provider it requires: |
| 151 | + |
| 152 | + |
| 153 | + |
| 154 | +### Connect your agentic client to an MCP gateway |
| 155 | + |
| 156 | +Create an [MCP gateway](/guides/mcp-gateways) that exposes your server's tools, then connect your client to the gateway URL (`https://api.arcade.dev/mcp/<your-gateway>`). |
| 157 | + |
| 158 | +### Call a tool |
| 159 | + |
| 160 | +Ask the agent to do something that uses one of your tools. The first time, Arcade returns a Cisco Duo authorization link. The user signs in and approves the Duo Push, then the tool runs. Subsequent calls reuse the authorization. |
| 161 | + |
| 162 | + |
| 163 | + |
| 164 | +</Steps> |
| 165 | + |
| 166 | +## Create your own Duo-authorized tools |
| 167 | + |
| 168 | +Tools that call the APIs, databases, and enterprise systems protected by Cisco Duo are built like any other Arcade tool, so follow the [Add user authorization to your tools](/guides/create-tools/tool-basics/create-tool-auth) and [Build an MCP server](/guides/create-tools/tool-basics/build-mcp-server) guides. |
| 169 | + |
| 170 | +The only Duo-specific part is the auth requirement on each tool: use the `OAuth2` class with the provider ID you configured and the scopes the tool needs. |
| 171 | + |
| 172 | +```python |
| 173 | +from arcade_mcp_server.auth import OAuth2 |
| 174 | + |
| 175 | +requires_auth = OAuth2(id="cisco-duo-oidc", scopes=["openid", "profile", "email"]) |
| 176 | +``` |
0 commit comments