Configure AWS Bedrock OAuth2 Credential Providers

The aws:bedrock/agentcoreOauth2CredentialProvider:AgentcoreOauth2CredentialProvider resource, part of the Pulumi AWS provider, configures OAuth2 credential providers that Bedrock agents use to authenticate with external services. This guide focuses on three capabilities: GitHub OAuth integration, OpenID Connect discovery, and manual authorization server configuration.

Credential providers require OAuth client credentials from your identity provider and either a discovery URL or explicit endpoint configuration. The examples are intentionally small. Combine them with your Bedrock agent configuration and secrets management.

Connect to GitHub’s OAuth service

Bedrock agents that need to authenticate with GitHub APIs use GitHub’s OAuth provider to obtain access tokens.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const github = new aws.bedrock.AgentcoreOauth2CredentialProvider("github", {
    name: "github-oauth-provider",
    credentialProviderVendor: "GithubOauth2",
    oauth2ProviderConfig: {
        githubOauth2ProviderConfig: {
            clientId: "your-github-client-id",
            clientSecret: "your-github-client-secret",
        },
    },
});
import pulumi
import pulumi_aws as aws

github = aws.bedrock.AgentcoreOauth2CredentialProvider("github",
    name="github-oauth-provider",
    credential_provider_vendor="GithubOauth2",
    oauth2_provider_config={
        "github_oauth2_provider_config": {
            "client_id": "your-github-client-id",
            "client_secret": "your-github-client-secret",
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/bedrock"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bedrock.NewAgentcoreOauth2CredentialProvider(ctx, "github", &bedrock.AgentcoreOauth2CredentialProviderArgs{
			Name:                     pulumi.String("github-oauth-provider"),
			CredentialProviderVendor: pulumi.String("GithubOauth2"),
			Oauth2ProviderConfig: &bedrock.AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs{
				GithubOauth2ProviderConfig: &bedrock.AgentcoreOauth2CredentialProviderOauth2ProviderConfigGithubOauth2ProviderConfigArgs{
					ClientId:     pulumi.String("your-github-client-id"),
					ClientSecret: pulumi.String("your-github-client-secret"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var github = new Aws.Bedrock.AgentcoreOauth2CredentialProvider("github", new()
    {
        Name = "github-oauth-provider",
        CredentialProviderVendor = "GithubOauth2",
        Oauth2ProviderConfig = new Aws.Bedrock.Inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs
        {
            GithubOauth2ProviderConfig = new Aws.Bedrock.Inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigGithubOauth2ProviderConfigArgs
            {
                ClientId = "your-github-client-id",
                ClientSecret = "your-github-client-secret",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.bedrock.AgentcoreOauth2CredentialProvider;
import com.pulumi.aws.bedrock.AgentcoreOauth2CredentialProviderArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigGithubOauth2ProviderConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var github = new AgentcoreOauth2CredentialProvider("github", AgentcoreOauth2CredentialProviderArgs.builder()
            .name("github-oauth-provider")
            .credentialProviderVendor("GithubOauth2")
            .oauth2ProviderConfig(AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs.builder()
                .githubOauth2ProviderConfig(AgentcoreOauth2CredentialProviderOauth2ProviderConfigGithubOauth2ProviderConfigArgs.builder()
                    .clientId("your-github-client-id")
                    .clientSecret("your-github-client-secret")
                    .build())
                .build())
            .build());

    }
}
resources:
  github:
    type: aws:bedrock:AgentcoreOauth2CredentialProvider
    properties:
      name: github-oauth-provider
      credentialProviderVendor: GithubOauth2
      oauth2ProviderConfig:
        githubOauth2ProviderConfig:
          clientId: your-github-client-id
          clientSecret: your-github-client-secret

The credentialProviderVendor property specifies GithubOauth2 to use GitHub’s OAuth service. The oauth2ProviderConfig contains githubOauth2ProviderConfig with your GitHub OAuth application’s clientId and clientSecret. Bedrock uses these credentials to obtain access tokens when your agent needs to interact with GitHub APIs.

Configure OAuth using OpenID Connect discovery

Many OAuth providers publish their configuration through OpenID Connect discovery endpoints, allowing automatic retrieval of authorization and token endpoints.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const auth0 = new aws.bedrock.AgentcoreOauth2CredentialProvider("auth0", {
    name: "auth0-oauth-provider",
    credentialProviderVendor: "CustomOauth2",
    customOauth2ProviderConfig: [{
        custom: [{
            clientIdWo: "auth0-client-id",
            clientSecretWo: "auth0-client-secret",
            clientCredentialsWoVersion: 1,
            oauthDiscovery: [{
                discoveryUrl: "https://dev-company.auth0.com/.well-known/openid-configuration",
            }],
        }],
    }],
});
import pulumi
import pulumi_aws as aws

auth0 = aws.bedrock.AgentcoreOauth2CredentialProvider("auth0",
    name="auth0-oauth-provider",
    credential_provider_vendor="CustomOauth2",
    custom_oauth2_provider_config=[{
        "custom": [{
            "clientIdWo": "auth0-client-id",
            "clientSecretWo": "auth0-client-secret",
            "clientCredentialsWoVersion": 1,
            "oauthDiscovery": [{
                "discoveryUrl": "https://dev-company.auth0.com/.well-known/openid-configuration",
            }],
        }],
    }])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/bedrock"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bedrock.NewAgentcoreOauth2CredentialProvider(ctx, "auth0", &bedrock.AgentcoreOauth2CredentialProviderArgs{
			Name:                     pulumi.String("auth0-oauth-provider"),
			CredentialProviderVendor: pulumi.String("CustomOauth2"),
			CustomOauth2ProviderConfig: []map[string]interface{}{
				map[string]interface{}{
					"custom": []map[string]interface{}{
						map[string]interface{}{
							"clientIdWo":                 "auth0-client-id",
							"clientSecretWo":             "auth0-client-secret",
							"clientCredentialsWoVersion": 1,
							"oauthDiscovery": []map[string]interface{}{
								map[string]interface{}{
									"discoveryUrl": "https://dev-company.auth0.com/.well-known/openid-configuration",
								},
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var auth0 = new Aws.Bedrock.AgentcoreOauth2CredentialProvider("auth0", new()
    {
        Name = "auth0-oauth-provider",
        CredentialProviderVendor = "CustomOauth2",
        CustomOauth2ProviderConfig = new[]
        {
            
            {
                { "custom", new[]
                {
                    
                    {
                        { "clientIdWo", "auth0-client-id" },
                        { "clientSecretWo", "auth0-client-secret" },
                        { "clientCredentialsWoVersion", 1 },
                        { "oauthDiscovery", new[]
                        {
                            
                            {
                                { "discoveryUrl", "https://dev-company.auth0.com/.well-known/openid-configuration" },
                            },
                        } },
                    },
                } },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.bedrock.AgentcoreOauth2CredentialProvider;
import com.pulumi.aws.bedrock.AgentcoreOauth2CredentialProviderArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var auth0 = new AgentcoreOauth2CredentialProvider("auth0", AgentcoreOauth2CredentialProviderArgs.builder()
            .name("auth0-oauth-provider")
            .credentialProviderVendor("CustomOauth2")
            .customOauth2ProviderConfig(List.of(Map.of("custom", List.of(Map.ofEntries(
                Map.entry("clientIdWo", "auth0-client-id"),
                Map.entry("clientSecretWo", "auth0-client-secret"),
                Map.entry("clientCredentialsWoVersion", 1),
                Map.entry("oauthDiscovery", List.of(Map.of("discoveryUrl", "https://dev-company.auth0.com/.well-known/openid-configuration")))
            )))))
            .build());

    }
}
resources:
  auth0:
    type: aws:bedrock:AgentcoreOauth2CredentialProvider
    properties:
      name: auth0-oauth-provider
      credentialProviderVendor: CustomOauth2
      customOauth2ProviderConfig:
        - custom:
            - clientIdWo: auth0-client-id
              clientSecretWo: auth0-client-secret
              clientCredentialsWoVersion: 1
              oauthDiscovery:
                - discoveryUrl: https://dev-company.auth0.com/.well-known/openid-configuration

The discoveryUrl property points to the provider’s well-known OpenID configuration endpoint. Bedrock automatically retrieves the authorization endpoint, token endpoint, and other OAuth metadata from this URL. The clientIdWo and clientSecretWo properties provide your OAuth client credentials. This approach simplifies configuration by eliminating the need to manually specify individual endpoints.

Define OAuth endpoints explicitly

When discovery URLs aren’t available or you need precise control over endpoint configuration, you can specify authorization server metadata directly.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const keycloak = new aws.bedrock.AgentcoreOauth2CredentialProvider("keycloak", {
    name: "keycloak-oauth-provider",
    credentialProviderVendor: "CustomOauth2",
    oauth2ProviderConfig: {
        customOauth2ProviderConfig: {
            clientIdWo: "keycloak-client-id",
            clientSecretWo: "keycloak-client-secret",
            clientCredentialsWoVersion: 1,
            oauthDiscovery: {
                authorizationServerMetadata: {
                    issuer: "https://auth.company.com/realms/production",
                    authorizationEndpoint: "https://auth.company.com/realms/production/protocol/openid-connect/auth",
                    tokenEndpoint: "https://auth.company.com/realms/production/protocol/openid-connect/token",
                    responseTypes: [
                        "code",
                        "id_token",
                    ],
                },
            },
        },
    },
});
import pulumi
import pulumi_aws as aws

keycloak = aws.bedrock.AgentcoreOauth2CredentialProvider("keycloak",
    name="keycloak-oauth-provider",
    credential_provider_vendor="CustomOauth2",
    oauth2_provider_config={
        "custom_oauth2_provider_config": {
            "client_id_wo": "keycloak-client-id",
            "client_secret_wo": "keycloak-client-secret",
            "client_credentials_wo_version": 1,
            "oauth_discovery": {
                "authorization_server_metadata": {
                    "issuer": "https://auth.company.com/realms/production",
                    "authorization_endpoint": "https://auth.company.com/realms/production/protocol/openid-connect/auth",
                    "token_endpoint": "https://auth.company.com/realms/production/protocol/openid-connect/token",
                    "response_types": [
                        "code",
                        "id_token",
                    ],
                },
            },
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/bedrock"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bedrock.NewAgentcoreOauth2CredentialProvider(ctx, "keycloak", &bedrock.AgentcoreOauth2CredentialProviderArgs{
			Name:                     pulumi.String("keycloak-oauth-provider"),
			CredentialProviderVendor: pulumi.String("CustomOauth2"),
			Oauth2ProviderConfig: &bedrock.AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs{
				CustomOauth2ProviderConfig: &bedrock.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigArgs{
					ClientIdWo:                 pulumi.String("keycloak-client-id"),
					ClientSecretWo:             pulumi.String("keycloak-client-secret"),
					ClientCredentialsWoVersion: pulumi.Int(1),
					OauthDiscovery: &bedrock.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryArgs{
						AuthorizationServerMetadata: &bedrock.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryAuthorizationServerMetadataArgs{
							Issuer:                pulumi.String("https://auth.company.com/realms/production"),
							AuthorizationEndpoint: pulumi.String("https://auth.company.com/realms/production/protocol/openid-connect/auth"),
							TokenEndpoint:         pulumi.String("https://auth.company.com/realms/production/protocol/openid-connect/token"),
							ResponseTypes: pulumi.StringArray{
								pulumi.String("code"),
								pulumi.String("id_token"),
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var keycloak = new Aws.Bedrock.AgentcoreOauth2CredentialProvider("keycloak", new()
    {
        Name = "keycloak-oauth-provider",
        CredentialProviderVendor = "CustomOauth2",
        Oauth2ProviderConfig = new Aws.Bedrock.Inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs
        {
            CustomOauth2ProviderConfig = new Aws.Bedrock.Inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigArgs
            {
                ClientIdWo = "keycloak-client-id",
                ClientSecretWo = "keycloak-client-secret",
                ClientCredentialsWoVersion = 1,
                OauthDiscovery = new Aws.Bedrock.Inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryArgs
                {
                    AuthorizationServerMetadata = new Aws.Bedrock.Inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryAuthorizationServerMetadataArgs
                    {
                        Issuer = "https://auth.company.com/realms/production",
                        AuthorizationEndpoint = "https://auth.company.com/realms/production/protocol/openid-connect/auth",
                        TokenEndpoint = "https://auth.company.com/realms/production/protocol/openid-connect/token",
                        ResponseTypes = new[]
                        {
                            "code",
                            "id_token",
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.bedrock.AgentcoreOauth2CredentialProvider;
import com.pulumi.aws.bedrock.AgentcoreOauth2CredentialProviderArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryArgs;
import com.pulumi.aws.bedrock.inputs.AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryAuthorizationServerMetadataArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var keycloak = new AgentcoreOauth2CredentialProvider("keycloak", AgentcoreOauth2CredentialProviderArgs.builder()
            .name("keycloak-oauth-provider")
            .credentialProviderVendor("CustomOauth2")
            .oauth2ProviderConfig(AgentcoreOauth2CredentialProviderOauth2ProviderConfigArgs.builder()
                .customOauth2ProviderConfig(AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigArgs.builder()
                    .clientIdWo("keycloak-client-id")
                    .clientSecretWo("keycloak-client-secret")
                    .clientCredentialsWoVersion(1)
                    .oauthDiscovery(AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryArgs.builder()
                        .authorizationServerMetadata(AgentcoreOauth2CredentialProviderOauth2ProviderConfigCustomOauth2ProviderConfigOauthDiscoveryAuthorizationServerMetadataArgs.builder()
                            .issuer("https://auth.company.com/realms/production")
                            .authorizationEndpoint("https://auth.company.com/realms/production/protocol/openid-connect/auth")
                            .tokenEndpoint("https://auth.company.com/realms/production/protocol/openid-connect/token")
                            .responseTypes(                            
                                "code",
                                "id_token")
                            .build())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  keycloak:
    type: aws:bedrock:AgentcoreOauth2CredentialProvider
    properties:
      name: keycloak-oauth-provider
      credentialProviderVendor: CustomOauth2
      oauth2ProviderConfig:
        customOauth2ProviderConfig:
          clientIdWo: keycloak-client-id
          clientSecretWo: keycloak-client-secret
          clientCredentialsWoVersion: 1
          oauthDiscovery:
            authorizationServerMetadata:
              issuer: https://auth.company.com/realms/production
              authorizationEndpoint: https://auth.company.com/realms/production/protocol/openid-connect/auth
              tokenEndpoint: https://auth.company.com/realms/production/protocol/openid-connect/token
              responseTypes:
                - code
                - id_token

The authorizationServerMetadata property defines the OAuth endpoints explicitly. The issuer identifies the authorization server, while authorizationEndpoint and tokenEndpoint specify where Bedrock sends OAuth requests. The responseTypes array lists the OAuth response types your provider supports. This approach gives you complete control over endpoint configuration without relying on discovery.

Beyond these examples

These snippets focus on specific credential provider features: GitHub OAuth integration, OpenID Connect discovery, and explicit authorization server configuration. They’re intentionally minimal rather than full Bedrock agent deployments.

The examples require pre-existing infrastructure such as OAuth client credentials from the identity provider, and OAuth provider endpoints or discovery URLs. They focus on configuring the credential provider rather than provisioning the complete agent workflow.

To keep things focused, common credential provider patterns are omitted, including:

  • Secrets Manager integration for client secrets (clientSecretArns output)
  • Other OAuth vendors (Google, Microsoft, Salesforce, Slack)
  • Region-specific deployment (region property)
  • Bedrock agent configuration that uses these credential providers

These omissions are intentional: the goal is to illustrate how each OAuth configuration approach is wired, not provide drop-in agent modules. See the Bedrock AgentCore OAuth2 Credential Provider resource reference for all available configuration options.

Let's configure AWS Bedrock OAuth2 Credential Providers

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Provider Configuration & Setup
What OAuth providers are supported?
Six providers are supported: CustomOauth2, GithubOauth2, GoogleOauth2, Microsoft, SalesforceOauth2, and SlackOauth2. Specify the provider using the credentialProviderVendor property.
Can I configure multiple OAuth providers in one resource?
No, oauth2ProviderConfig must contain exactly one provider type. Create separate resources for each OAuth provider you need.
How do I set up GitHub OAuth authentication?
Set credentialProviderVendor to GithubOauth2 and configure oauth2ProviderConfig.githubOauth2ProviderConfig with your clientId and clientSecret.
OAuth Configuration Methods & Security
What's the difference between using a discovery URL and authorization server metadata for custom OAuth?
Discovery URL automatically fetches OAuth configuration from an OIDC endpoint (like .well-known/openid-configuration), while authorization server metadata requires you to explicitly specify the issuer, authorization endpoint, token endpoint, and response types.
Where are my OAuth client secrets stored?
Client secrets are stored in AWS Secrets Manager. The ARNs of these secrets are available in the clientSecretArns output property after resource creation.
Which region is my OAuth provider created in?
The provider is created in the region specified by the region property, which defaults to your AWS provider configuration if not explicitly set.

Using a different cloud?

Explore security guides for other cloud providers: