Give each third-party token the minimum permissions the tool needs. We store the credential and use it as issued. We do not limit its scope.
How to Authorize Providers with Connectionspublic
Last verified 22 Oct 2026
Action Gateway connects applications and AI agents to tools through a managed MCP endpoint or SDK, with the accounts and permissions you choose. See What You Can Build for standalone agent examples.
Connect an account to let Action Gateway tools work with your GitHub repositories, Linear issues, or another service’s resources. The service is the tool provider, and the saved account access is a connection. You can connect your own account or have an application user authorize theirs.
Create the connection under the same DigitalOcean user and team as the session that needs it, using that session’s Actor ID. You can connect accounts before or after creating a session. Public tools that do not need your own provider credentials skip this step.
Provider consent is separate from signing your MCP client in to DigitalOcean and approving individual tool calls. To get an MCP URL and connect your client, see Connect Action Gateway Tools.
If the provider you need is not listed, add its remote MCP server as a custom provider first. Custom providers support no authentication, an API key, or an OAuth connection.
For providers that support VPC networking, a connection also selects the VPC and destinations used by its tool calls. VPC networking must be enabled for your team and is available in ric1. See Access Tools and MCP Servers on a Private Network for the network model and setup paths.
Choose How a Connection Authenticates
Every connection identifies a provider, an actor ID, and an authentication type:
- None: The provider requires no authentication.
- OAuth: Authorize the provider account through DigitalOcean’s OAuth application or your own.
- Provider secret: Use a stored credential, such as an API key.
Choose the authentication type the provider expects. For credentials, grant only the permissions the tools need in the third-party product. Configure VPC access separately when the provider is on a private network.
Create a Connection at Runtime
You do not have to set up a connection in advance. When a tool requires provider access, Action Gateway can return a requires_authorization response with instructions to connect the account. A call waiting for this authorization does not execute.
For supported OAuth providers, complete the consent flow at the returned link and check the verification code. For providers requiring your own API key or OAuth application, follow the setup link instead. A compatible MCP client can keep the original call open and continue after authorization. If the call has already returned an authorization-required result, retry after completing authorization. Do not submit a duplicate while the original call is still waiting.
This suits interactive work where someone can complete sign-in. Do not rely on it for an unattended job.
Create a Connection Ahead of Time
For unattended workloads that cannot pause for a provider sign-in, create the connection before the application runs.
Create a Connection Using the Control Panel
- Go to the Connections page.
- Click Add connection.
- Select the provider, then choose an authentication method:
- DigitalOcean’s OAuth app when the provider supports DigitalOcean-managed OAuth.
- Your own OAuth client or Your own API key when you supply credentials. Register a new credential in the form, or select an available credential under Manage credentials.
- None when the provider requires no authentication.
- Use the same Actor ID as the session that needs this account. For your own coding agent, you can use the Control Panel default. For an application serving multiple users, use a separate label for each person, such as
user-123. - Review the Permissions (scopes) if the provider requests them, then click Connect.
- If the provider uses OAuth, sign in with the account you want the tools to access and approve the requested permissions. Wait until the connection shows Active.
Other team members do not gain permission to use your connection by entering the same actor ID. See Connection Ownership.
A connection that a Harness Runtime Environment Config depends on is deletion protected. Deleting it from the Connections page requires clicking Force delete and acknowledging the override, which bypasses the in-use check that Harness Runtime applies. Sessions then fail to start from any config that depends on the connection. To delete it safely, revoke it from Harness Runtime instead, which names the configs to delete first.
Create a Connection Using the SDK
Create a connection with PyDo, Godo, or DoTs. These examples use DigitalOcean’s shared OAuth app for GitHub.
First, create a DigitalOcean personal access token and set it privately as DIGITALOCEAN_TOKEN in your local environment. This token lets your code create and manage Action Gateway resources. Use a token from the DigitalOcean user and team that own the session.
Replace <actor-id> with the Actor ID from your session’s details. If you have not created a session yet, use the Control Panel default and keep that value when creating the session.
For an application serving other users, choose a separate label for each person. For example, if your application stores a customer’s user record under user-123, use user-123 for both their connection and session. Signing in to GitHub in the next step determines which GitHub account the tools access, not the label you choose.
The SDKs use different field names for this same label:
| SDK | Connection field | Session field |
|---|---|---|
| PyDo | user_id |
actor_id |
| Godo | UserID |
ActorID |
| DoTs | userId |
actorId |
Run the examples locally to connect your own account. If authorization is required, open the returned authorization URL, compare its verification code, and sign in with the GitHub account you want the tools to access. For another person’s account, follow Connect an Application User’s Account.
Keep authorization URLs, verification codes, and tokens out of agent conversations, source files, and application logs. The example requests GitHub’s repo scope. Request only the scopes your workload needs.
Install PyDo:
pip install pydoRun the following code in a local Python interpreter to start a GitHub connection:
import os
from pydo.action_gateway import ActionGatewayClient
ag_client = ActionGatewayClient(token=os.environ["DIGITALOCEAN_TOKEN"])
response = ag_client.connections.create(
body={
"provider": "github",
"user_id": "<actor-id>",
"scopes": ["repo"],
},
)
connection_id = response["connection"]["id"]
authorization = response.get("authorization")
if authorization:
print("Authorization URL:", authorization["connect_url"])
print("Verification code:", authorization["verification_code"])
print("Connection status:", response["connection"]["status"])After completing authorization in your browser, run this status check in the same Python interpreter:
response = ag_client.connections.get(id=connection_id)
print(response["connection"]["status"])Install the DoTs build with Action Gateway support:
npm install @digitalocean/[email protected]Use your local DIGITALOCEAN_TOKEN environment variable and the session’s actor ID to start a GitHub connection:
import { ActionGatewayClient } from "@digitalocean/dots/action_gateway";
const agClient = new ActionGatewayClient({
apiKey: process.env.DIGITALOCEAN_TOKEN!,
});
const response = await agClient.connections.post({
provider: "github",
userId: "<actor-id>",
scopes: ["repo"],
});
const connectionId = response?.connection?.id;
if (!connectionId) {
throw new Error("Connection creation returned no connection ID.");
}
if (response?.authorization) {
console.log("Authorization URL:", response.authorization.connectUrl);
console.log("Verification code:", response.authorization.verificationCode);
}
console.log("Connection status:", response?.connection?.status);After completing authorization in your browser, use the returned connection ID to check its status:
const statusResponse = await agClient.connections.byId(connectionId).get();
console.log(statusResponse?.connection?.status);Install Godo:
go get github.com/digitalocean/godoUse your local DIGITALOCEAN_TOKEN environment variable and the session’s actor ID to start a GitHub connection:
package main
import (
"context"
"fmt"
"os"
"github.com/digitalocean/godo"
)
func main() {
client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN"))
ctx := context.Background()
response, _, err := client.ActionGateway.Connections.Create(ctx, &godo.ActionGatewayConnectionCreateRequest{
Provider: "github",
UserID: "<actor-id>",
Scopes: []string{"repo"},
})
if err != nil {
panic(err)
}
connectionID := response.Connection.ID
if response.Authorization != nil {
fmt.Println("Authorization URL:", response.Authorization.ConnectURL)
fmt.Println("Verification code:", response.Authorization.VerificationCode)
}
fmt.Println("Connection status:", response.Connection.Status)
statusResponse, _, err := client.ActionGateway.Connections.Get(ctx, connectionID)
if err != nil {
panic(err)
}
fmt.Println(statusResponse.Connection.Status)
}After completing authorization in your browser, re-run the Connections.Get call with the returned connection ID to confirm the status is active.
The connection is ready when its status is active. If it is still pending, finish the browser authorization and repeat the status check. Use the existing connection ID for status checks rather than creating another connection.
Configure a Private Connection
In the connection form, select Reach a service in a VPC. VPC networking must be enabled for your team. This option also requires permission to read VPCs and a provider that supports VPC connections.
Under VPC Attachment, select a VPC owned by your team in ric1. Enter the Destination host and Destination port that the provider’s tools need. The host is a hostname or IP address, without a scheme or path. For https://mcp.example.com/mcp, enter mcp.example.com and 443.
Use Add destination for another host and port.
Allowed IP ranges (optional) limits the private IP addresses of the service you are connecting to. These are destination addresses, not your client’s IP or Action Gateway’s source IP. Enter comma-separated CIDRs.
Use this field when a hostname should resolve only within a known subnet. For example, if mcp.example.com should point to servers in 10.20.0.0/24, enter that range. Action Gateway refuses the call if any DNS answer falls outside it. This prevents a DNS change from directing calls to another private subnet.
Leave the field blank if you do not need this extra IP restriction. The destination host, port, and private-address checks still apply. When the destination host is already a fixed IP address, such as 10.20.0.10, it already identifies the allowed address.
In the API, add network to the connection creation request:
{
"network": {
"vpc": {
"vpc_uuid": "<vpc-uuid>",
"destinations": [
{
"host": "mcp.example.com",
"port": 443,
"allowed_ip_cidrs": ["10.20.0.0/24"]
}
]
}
}
}Replace <vpc-uuid> with your VPC ID and the destination values with your service’s host, port, and IP range.
To replace an existing connection’s network through PATCH /v2/action-gateway/connections/<connection-id>, send the complete replacement network and "update_mask": "network". Omitting network from the update mask preserves it. Including that mask without a network value removes the private settings. A private MCP provider then refuses calls until the connection has a matching network again.
A private MCP connection must match the server’s registered VPC ID and region, and its destinations must include the MCP endpoint’s host and port. An attached session must be in the connection’s region. Use the same VPC for the server, connection, and session when setting up your first provider.
For a private MCP provider, the form fills the server’s VPC and endpoint destination. Review those settings, enter the actor ID, and choose the provider’s authentication type before clicking Connect.
For an unauthenticated provider, the API example uses "credential": {"none": {}}. The connection request also includes the provider, actor ID as user_id, and VPC network settings. See Custom Providers for the private MCP setup sequence.
Connect an Application User’s Account
Your application can create a connection on behalf of a user who does not have a DigitalOcean account. The backend owns the Action Gateway resources. The user grants access to their external account:
- Authenticate the user in your application and look up the actor ID assigned to them, such as
user-123. Do not accept another user’s actor ID from an untrusted request. - From your backend, create the connection with your DigitalOcean credentials and that actor ID, using the SDK request shown earlier.
- If authorization is required, present the returned authorization URL and verification code only to that user through your authenticated application. Have them compare the code on the consent page, sign in to the provider, and approve the requested permissions. This consent page does not require a DigitalOcean login.
- Check the connection status from your backend using its connection ID. Wait for
activebefore running tools that need it. - Create or reuse a session owned by the same DigitalOcean user and team with that actor ID. Execute the user’s tool calls through your backend.
Do not send your DigitalOcean token to the application user or the model. The user’s provider sign-in does not grant permission to call the MCP URL directly as a different DigitalOcean user. See Connection Ownership.
Scope Connections to an Actor
To use the connected account, create a session with the same actor ID. In PyDo, pass the connection’s user_id value as the session’s actor_id. Continue in the Python interpreter with the same authenticated client and replace <actor-id> with the value you used earlier:
session = ag_client.session.create(
actor_id="<actor-id>",
)Later sessions owned by the same DigitalOcean user in the same team can reuse these connections by specifying the same actor ID. For example, use user-123-work and user-123-personal for one user’s work and personal GitHub accounts, then select the appropriate ID when creating each session. Calls through that session’s MCP URL use the selected actor’s connections.
Actor IDs do not authenticate your application’s users. Your application must authenticate each user and select the correct actor ID before creating or using a session. See Actors.
Restore Provider Access
Keep the connection’s actor ID when restoring access. Existing sessions look up the connection on later calls, so reauthorization does not require a new session or MCP URL.
For a pending, expired, or revoked OAuth connection in the Control Panel:
- Go to the Connections page as the DigitalOcean user who owns the connection.
- Find the provider and actor ID used by the affected session. Open the connection’s actions menu and select Reconnect.
- Review the requested permissions and complete provider authorization. Confirm that the connection returns to Active.
- If the original call is still waiting for consent, let the client continue it. If it has already failed or returned
requires_authorization, check whether the earlier attempt made changes before retrying. Do not submit a duplicate call while the original is waiting.
If the connection still shows Active but a tool requests authorization, use the consent link returned by that call. Reconnect is available only for pending, expired, or revoked connections. The connection’s saved status does not guarantee that the provider still accepts its credentials.
If access was revoked at the provider, the connection can still show Active while calls fail with a provider authentication error and no consent link. Revoke the connection and authorize the account again under the same actor ID. For a deletion-protected connection, first remove its Harness Runtime dependencies.
For an application user’s account, present the authorization link from the affected tool response to that user through your application. For a pending, expired, or revoked connection, you can also repeat connection creation from your backend with the same actor, provider, and credential choice. Complete the returned flow before resuming work. Do not change the actor to work around an authorization error.
| Problem | Recovery |
|---|---|
| Provider access token expires | Action Gateway can refresh it when the provider supplies a valid refresh credential. If authorization is requested again, reconnect the account. |
| Consent link expires or authorization remains pending | Restart authorization and complete the new link before it expires. Keep the session’s MCP URL. |
| Provider access is revoked or refresh fails | Have the account holder authorize again. If calls return authentication errors without a consent link, revoke the connection and create it again for the same actor. Pause or fail dependent work until access is restored. |
| Tool needs permissions the account did not grant | Revoke the connection, then create it again for the same actor with the required provider permissions and obtain consent. Allowing the tool in the session policy does not add provider permissions. |
| API key is expired, revoked, or insufficiently privileged | Restore the key’s access at the provider, or revoke and recreate the connection with a replacement credential. Changing the credential binding requires recreating the connection. |
| Another DigitalOcean user owns the connection | Create a connection under the session owner’s identity. Matching the actor ID alone does not share access. |
Revoking or replacing a connection affects all sessions that use it. Coordinate credential changes with running workloads. A provider failure is not a reason to broaden the session’s tools or disable its approval policy.
View Actors
You can view the actors for your agent in the Actors tab of Action Gateway in the Control Panel.