The gcp:developerconnect/accountConnector:AccountConnector resource, part of the Pulumi GCP provider, establishes OAuth connections between Developer Connect and external services like GitHub, GitLab, or Google APIs. This guide focuses on two capabilities: OAuth provider configuration and scope-based authorization for different services.
Account connectors require a GCP project with the Developer Connect API enabled. The examples are intentionally small. Combine them with your own OAuth credentials and service-specific configuration.
Connect to GitHub repositories with OAuth
Teams building CI/CD pipelines or code analysis tools need programmatic access to GitHub repositories. Account connectors establish OAuth connections that Developer Connect uses to interact with external services.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const my_account_connector = new gcp.developerconnect.AccountConnector("my-account-connector", {
location: "us-central1",
accountConnectorId: "tf-test-ac",
providerOauthConfig: {
systemProviderId: "GITHUB",
scopes: ["repo"],
},
});
import pulumi
import pulumi_gcp as gcp
my_account_connector = gcp.developerconnect.AccountConnector("my-account-connector",
location="us-central1",
account_connector_id="tf-test-ac",
provider_oauth_config={
"system_provider_id": "GITHUB",
"scopes": ["repo"],
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/developerconnect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := developerconnect.NewAccountConnector(ctx, "my-account-connector", &developerconnect.AccountConnectorArgs{
Location: pulumi.String("us-central1"),
AccountConnectorId: pulumi.String("tf-test-ac"),
ProviderOauthConfig: &developerconnect.AccountConnectorProviderOauthConfigArgs{
SystemProviderId: pulumi.String("GITHUB"),
Scopes: pulumi.StringArray{
pulumi.String("repo"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var my_account_connector = new Gcp.DeveloperConnect.AccountConnector("my-account-connector", new()
{
Location = "us-central1",
AccountConnectorId = "tf-test-ac",
ProviderOauthConfig = new Gcp.DeveloperConnect.Inputs.AccountConnectorProviderOauthConfigArgs
{
SystemProviderId = "GITHUB",
Scopes = new[]
{
"repo",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.developerconnect.AccountConnector;
import com.pulumi.gcp.developerconnect.AccountConnectorArgs;
import com.pulumi.gcp.developerconnect.inputs.AccountConnectorProviderOauthConfigArgs;
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 my_account_connector = new AccountConnector("my-account-connector", AccountConnectorArgs.builder()
.location("us-central1")
.accountConnectorId("tf-test-ac")
.providerOauthConfig(AccountConnectorProviderOauthConfigArgs.builder()
.systemProviderId("GITHUB")
.scopes("repo")
.build())
.build());
}
}
resources:
my-account-connector:
type: gcp:developerconnect:AccountConnector
properties:
location: us-central1
accountConnectorId: tf-test-ac
providerOauthConfig:
systemProviderId: GITHUB
scopes:
- repo
The providerOauthConfig block defines the OAuth provider and requested permissions. The systemProviderId identifies the service (GITHUB, GITLAB, GOOGLE, etc.), while scopes controls what the connector can access. For GitHub, the “repo” scope grants full repository access. The location property determines where GCP stores the connector metadata, and accountConnectorId provides a unique identifier within that location.
Connect to GitLab with API access
GitLab integrations require API-level access to repositories, issues, and merge requests.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const my_account_connector = new gcp.developerconnect.AccountConnector("my-account-connector", {
location: "us-central1",
accountConnectorId: "tf-test-ac",
providerOauthConfig: {
systemProviderId: "GITLAB",
scopes: ["api"],
},
});
import pulumi
import pulumi_gcp as gcp
my_account_connector = gcp.developerconnect.AccountConnector("my-account-connector",
location="us-central1",
account_connector_id="tf-test-ac",
provider_oauth_config={
"system_provider_id": "GITLAB",
"scopes": ["api"],
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/developerconnect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := developerconnect.NewAccountConnector(ctx, "my-account-connector", &developerconnect.AccountConnectorArgs{
Location: pulumi.String("us-central1"),
AccountConnectorId: pulumi.String("tf-test-ac"),
ProviderOauthConfig: &developerconnect.AccountConnectorProviderOauthConfigArgs{
SystemProviderId: pulumi.String("GITLAB"),
Scopes: pulumi.StringArray{
pulumi.String("api"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var my_account_connector = new Gcp.DeveloperConnect.AccountConnector("my-account-connector", new()
{
Location = "us-central1",
AccountConnectorId = "tf-test-ac",
ProviderOauthConfig = new Gcp.DeveloperConnect.Inputs.AccountConnectorProviderOauthConfigArgs
{
SystemProviderId = "GITLAB",
Scopes = new[]
{
"api",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.developerconnect.AccountConnector;
import com.pulumi.gcp.developerconnect.AccountConnectorArgs;
import com.pulumi.gcp.developerconnect.inputs.AccountConnectorProviderOauthConfigArgs;
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 my_account_connector = new AccountConnector("my-account-connector", AccountConnectorArgs.builder()
.location("us-central1")
.accountConnectorId("tf-test-ac")
.providerOauthConfig(AccountConnectorProviderOauthConfigArgs.builder()
.systemProviderId("GITLAB")
.scopes("api")
.build())
.build());
}
}
resources:
my-account-connector:
type: gcp:developerconnect:AccountConnector
properties:
location: us-central1
accountConnectorId: tf-test-ac
providerOauthConfig:
systemProviderId: GITLAB
scopes:
- api
The “api” scope grants full API access to GitLab resources. Different providers require different scope values; GitLab uses “api” for comprehensive access, while GitHub uses “repo” for repository operations.
Connect to Google services with scoped permissions
Some workflows need to access Google Drive or other Google services alongside code repositories.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const my_account_connector = new gcp.developerconnect.AccountConnector("my-account-connector", {
location: "us-central1",
accountConnectorId: "tf-test-ac",
providerOauthConfig: {
systemProviderId: "GOOGLE",
scopes: ["https://www.googleapis.com/auth/drive.readonly"],
},
});
import pulumi
import pulumi_gcp as gcp
my_account_connector = gcp.developerconnect.AccountConnector("my-account-connector",
location="us-central1",
account_connector_id="tf-test-ac",
provider_oauth_config={
"system_provider_id": "GOOGLE",
"scopes": ["https://www.googleapis.com/auth/drive.readonly"],
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/developerconnect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := developerconnect.NewAccountConnector(ctx, "my-account-connector", &developerconnect.AccountConnectorArgs{
Location: pulumi.String("us-central1"),
AccountConnectorId: pulumi.String("tf-test-ac"),
ProviderOauthConfig: &developerconnect.AccountConnectorProviderOauthConfigArgs{
SystemProviderId: pulumi.String("GOOGLE"),
Scopes: pulumi.StringArray{
pulumi.String("https://www.googleapis.com/auth/drive.readonly"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var my_account_connector = new Gcp.DeveloperConnect.AccountConnector("my-account-connector", new()
{
Location = "us-central1",
AccountConnectorId = "tf-test-ac",
ProviderOauthConfig = new Gcp.DeveloperConnect.Inputs.AccountConnectorProviderOauthConfigArgs
{
SystemProviderId = "GOOGLE",
Scopes = new[]
{
"https://www.googleapis.com/auth/drive.readonly",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.developerconnect.AccountConnector;
import com.pulumi.gcp.developerconnect.AccountConnectorArgs;
import com.pulumi.gcp.developerconnect.inputs.AccountConnectorProviderOauthConfigArgs;
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 my_account_connector = new AccountConnector("my-account-connector", AccountConnectorArgs.builder()
.location("us-central1")
.accountConnectorId("tf-test-ac")
.providerOauthConfig(AccountConnectorProviderOauthConfigArgs.builder()
.systemProviderId("GOOGLE")
.scopes("https://www.googleapis.com/auth/drive.readonly")
.build())
.build());
}
}
resources:
my-account-connector:
type: gcp:developerconnect:AccountConnector
properties:
location: us-central1
accountConnectorId: tf-test-ac
providerOauthConfig:
systemProviderId: GOOGLE
scopes:
- https://www.googleapis.com/auth/drive.readonly
Google services use URL-based scope identifiers. The “https://www.googleapis.com/auth/drive.readonly" scope grants read-only access to Google Drive. Each Google API defines its own scope URLs for different permission levels.
Beyond these examples
These snippets focus on specific account connector features: OAuth provider configuration and scope-based authorization. They’re intentionally minimal rather than full integration solutions.
The examples assume pre-existing infrastructure such as a GCP project with Developer Connect API enabled. They focus on connector configuration rather than OAuth credential setup or downstream service integration.
To keep things focused, common connector patterns are omitted, including:
- Annotations for arbitrary metadata (annotations)
- Labels for resource organization (labels)
- OAuth flow completion (oauthStartUri is output-only)
- Provider-specific authentication beyond OAuth scopes
These omissions are intentional: the goal is to illustrate how each connector feature is wired, not provide drop-in integration modules. See the AccountConnector resource reference for all available configuration options.
Let's configure GCP Developer Connect Account Connectors
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Provider Configuration
repo scope), GitLab (api scope), Google (full URL scopes like https://www.googleapis.com/auth/drive.readonly), Sentry (org:read scope), Rovo (rovo scope), New Relic (empty scopes), and Datastax (empty scopes). Configure these using providerOauthConfig.systemProviderId and providerOauthConfig.scopes.oauthStartUri output property to get a URL. Click this URL to begin the OAuth authorization flow with your chosen provider.Resource Management
accountConnectorId, location, and project properties are immutable. To change any of these, you must destroy and recreate the resource.projects/{{project}}/locations/{{location}}/accountConnectors/{{account_connector_id}}), project-relative ({{project}}/{{location}}/{{account_connector_id}}), or location-relative ({{location}}/{{account_connector_id}}).Labels & Annotations
labels and annotations fields are non-authoritative, meaning they only manage values present in your configuration. To see all labels and annotations on the resource (including those set by other clients), use effectiveLabels and effectiveAnnotations.Using a different cloud?
Explore integration guides for other cloud providers: