The aws:bedrock/agentcoreOauth2CredentialProvider:AgentcoreOauth2CredentialProvider resource, part of the Pulumi AWS provider, configures OAuth2 credential providers that enable Bedrock agents to authenticate with external identity providers. This guide focuses on three approaches: GitHub’s managed OAuth2 service, custom OAuth2 with OpenID Connect discovery, and explicit authorization server metadata.
All configurations require OAuth2 applications registered with your identity provider, along with client credentials. The examples are intentionally small. Combine them with your own agent configurations and secret management.
Connect to GitHub’s OAuth2 service
Teams building agents that interact with GitHub repositories use OAuth2 to access private resources without embedding personal 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 set to “GithubOauth2” tells Bedrock to use GitHub’s managed OAuth2 endpoints. The githubOauth2ProviderConfig block contains your GitHub OAuth App credentials. Bedrock handles token exchange and refresh automatically.
Configure custom OAuth2 with discovery URL
Organizations using Auth0, Okta, or other OpenID Connect providers can leverage discovery URLs to fetch OAuth2 configuration automatically.
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 points to your provider’s OpenID Connect discovery document, which contains authorization and token endpoints. Bedrock fetches this configuration at runtime. The clientIdWo and clientSecretWo properties are write-only variants that prevent credentials from appearing in state files (requires Terraform 1.11.0+).
Define OAuth2 endpoints explicitly
When discovery URLs aren’t available or you need explicit control, 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 block defines the issuer, authorization endpoint, token endpoint, and supported response types. This approach gives you full control over endpoint URLs, useful for custom OAuth2 implementations or when discovery isn’t supported. This is an alternative to the discovery URL approach shown earlier.
Beyond these examples
These snippets focus on specific credential provider features: managed OAuth2 providers (GitHub), custom OAuth2 with discovery, and explicit endpoint configuration. They’re intentionally minimal rather than full agent authentication systems.
The examples assume pre-existing infrastructure such as OAuth2 applications registered with identity providers, and client credentials (ID and secret) from OAuth2 apps. They focus on configuring the credential provider rather than provisioning the OAuth2 applications themselves.
To keep things focused, common credential provider patterns are omitted, including:
- Write-only vs standard credential properties (clientIdWo vs clientId)
- Resource tagging for organization and cost tracking
- Regional deployment considerations
- Secrets Manager integration for credential storage
These omissions are intentional: the goal is to illustrate how each OAuth2 configuration is wired, not provide drop-in authentication 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 FREEFrequently Asked Questions
Configuration & Setup
CustomOauth2, GithubOauth2, GoogleOauth2, Microsoft, SalesforceOauth2, and SlackOauth2. Specify your choice using the credentialProviderVendor property.oauth2ProviderConfig must contain exactly one provider type. Choose either a built-in provider like GitHub or a custom OAuth2 configuration, but not both.credentialProviderVendor, name, and oauth2ProviderConfig. The region property is also required but defaults to your provider configuration.pulumi import aws:bedrock/agentcoreOauth2CredentialProvider:AgentcoreOauth2CredentialProvider example oauth2-provider-name with the provider’s name.Authentication & Credentials
client_id_wo and client_secret_wo are write-only arguments that don’t expose values in state. They require Terraform 1.11.0 or later, while client_id and client_secret work with earlier versions.client_id_wo and client_secret_wo when you need write-only semantics to avoid storing credentials in Terraform state. This requires Terraform 1.11.0 or later.clientSecretArns output property contains the ARN of the secret.Provider-Specific Configuration
credentialProviderVendor to GithubOauth2 and provide your GitHub client ID and secret in the githubOauth2ProviderConfig block./.well-known/openid-configuration), while manual metadata requires you to explicitly specify the issuer, authorization endpoint, token endpoint, and response types.credentialProviderVendor to CustomOauth2 and provide either a discoveryUrl for automatic configuration or manual authorizationServerMetadata with issuer, endpoints, and response types.