Git-Backed Content

Posit Connect publishers can deploy content to Connect in a variety of ways. One mechanism is to create content on Connect directly from a Git repository. The User Guide contains instructions on the steps taken by publishers.

Content deployed from a Git repository is indicated in the content’s Settings > Source panel with a Git Details section containing metadata about the source repository.

A given source repository can be associated with any number of applications.

Requirements

Note

Git >=2.31.0 is required for Git backed content.

The version of Git installed in the same environment as Posit Connect is detected at process startup time, and is subject to the PATH set in the process environment. Alternatively, the path to the git executable can be set directly via Git.Executable.

If the version of Git cannot be detected, or if the version is lower than the minimum required of 2.31.0, a warning is logged and Connect starts with Git backed content disabled for the entire server. Existing Git backed content is no longer polled for new commits and cannot be redeployed, and publishers cannot import content from Git. Check the installed version with git --version before you upgrade Connect. See Disabling to learn how to disable Git backed content support.

Publishing

Git backed content can be associated with either public or private Git repositories, and can use https:// (recommended) or http:// remotes.

The Applications.RunAs user runs all git commands necessary for retrieving repository data.

Note

Currently, Posit Connect Git-backed publishing does not support Git Large File Storage (LFS).

Public repositories

Publicly-accessible source repositories can be configured by any user with a publisher role.

Note

Git credentials grant access to private repositories. They do not limit which repositories publishers can use. Connect selects a GitCredential by matching the repository URL’s host and protocol, and clones with no credentials when no section matches. A publisher can therefore use any publicly readable repository on any host, whatever credentials you configure. Restrict outbound network access if your deployment must limit the repositories publishers can reach.

Private repositories

Private source repositories can be accessed by setting GitCredential.Host, GitCredential.Username, and GitCredential.Password, which works with any authentication based on HTTP basic auth, such as with GitHub personal access tokens.

/etc/rstudio-connect/rstudio-connect.gcfg
[GitCredential]
Host = github.com
Username = accountName
Password = <encrypted-string>
Protocol = https
Note

The encrypted string value of GitCredential.Password should be generated via rscadmin.

You can support multiple hosts by including additional GitCredential sections. Each host can only have a single credential. When configuring multiple credentials, you must name each configuration section. If two GitCredential sections share a name, Connect combines them into one section. A setting in the later section replaces the same setting in the earlier one, and settings that only the earlier section sets are kept.

/etc/rstudio-connect/rstudio-connect.gcfg
[GitCredential "github"]
Host = github.com
Username = accountName
Password = <encrypted-string>
Protocol = https

[GitCredential "selfhosted"]
Host = git.mycompany.com
Username = accountName
Password = <encrypted-string>
Protocol = https

Connect checks each GitCredential section at startup and logs a warning for each problem it finds. A problem in one section affects only Git-backed content on that section’s host. When two sections set the same Host, Connect treats both as invalid. For a host with an invalid section, publishers see an error that asks them to contact their administrator. A section whose Host is empty or is not a host name, such as github.com/my-org or https://github.com, never matches a repository, so the startup warning is its only report.

Connect can also use configured Git credentials to install packages from private Git repositories during environment restoration:

  • R packages: Connect uses credentials for github.com, gitlab.com, and bitbucket.org to restore R packages from private repositories on those services. See private R packages from Git repositories for details.

  • Python packages: Connect uses credentials for all configured GitCredential hosts to install Python packages specified as Git URL dependencies in requirements.txt. See private Python packages from Git repositories for details.

Note

For private packages, Posit recommends Posit Package Manager instead of Git credentials. Publish the packages to Package Manager and install them from a Package Manager repository. See Use private R and Python packages from Package Manager. Git credentials remain the way to deploy Git-backed content from private repositories.

OAuth authentication

Connect can authenticate to Git hosting platforms with OAuth access tokens instead of static passwords or personal access tokens. Short-lived tokens issued by an integration improve security and keep credential management in one place.

Note

Two kinds of OAuth integration can supply tokens for Git:

Connect determines which flow to use from the integration itself. GitCredential.OAuthIntegration accepts either type, and you do not configure anything else to choose between them.

Important

Bearer token authentication (the default mode when GitCredential.Username is not set) requires git 2.31 or later. This version introduced support for passing git configuration through environment variables, which Connect uses to keep OAuth tokens out of process listings for security reasons. Verify your installed git version with git --version before enabling this feature.

To use OAuth authentication for Git, you must:

  1. Configure your Git hosting platform to allow OAuth-based authentication
  2. Create a service account integration or a GitHub App integration in Connect using the credentials from your platform
  3. Configure the GitCredential in Connect to reference the integration by name

Setting the username

The GitCredential.Username setting controls how Connect presents the OAuth token to Git. Set it to match your platform:

  • GitHub: set Username to x-access-token. Connect sends the token as the HTTP basic auth password.
  • Azure DevOps: omit Username. Connect sends the token as a bearer token in an Authorization request header.

For another platform, set Username if the platform expects the token as a basic auth password, and omit it if the platform expects a bearer token.

OAuth with Azure DevOps

Azure DevOps supports OAuth authentication for Git operations using service principals. The following steps outline how to configure this integration.

For complete details, see Microsoft’s documentation on using service principals with Azure DevOps.

Step 1: Register an application in Entra ID

Create an app registration in the Azure portal:

  1. Navigate to Microsoft Entra ID → App registrations → New registration
  2. Enter a name for the application (e.g., “Connect Git Integration”)
  3. Select the appropriate supported account type for your organization
  4. Register the application
Step 2: Capture required values

From your app registration, note the following values:

  • Tenant ID
  • Client ID (Application ID)
  • Client secret (create one under Certificates & secrets)
  • Enterprise application object ID (found under Enterprise applications, not the app registration object ID) — this is the service principal ID used when adding to Azure DevOps
Step 3: Add the service principal to Azure DevOps

Add the Entra ID application as a service principal in Azure DevOps using the enterprise application object ID from Step 2:

  1. In Azure DevOps, navigate to Organization settings → Users
  2. Select Add users and search for the app registration name or enterprise application object ID
  3. Add the service principal with the appropriate access level (e.g., Basic)
  4. Grant the service principal access to the projects and repositories it needs
Important

Add the service principal to Azure DevOps before configuring OAuth authentication. Without this step, authentication will fail even with valid OAuth tokens.

Step 4: Create the integration in Connect

Create a service account integration in Connect with the following values from your app registration:

  • Name: The name you assign here must match the value you set in GitCredential.OAuthIntegration (e.g., my-git-oauth-integration)
  • Integration type: Custom or Azure (depending on your setup)
  • Token URL: https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
  • Client ID: Your application’s client ID
  • Client secret: Your application’s client secret
  • Scopes: https://app.vssps.visualstudio.com/.default
Important

When creating the integration for Git, set the access control list (ACL) to restrict access to administrators only. This prevents publishers from accidentally associating the Git integration with published content.

Step 5: Configure Connect

Update your Connect configuration to reference the integration by its name:

/etc/rstudio-connect/rstudio-connect.gcfg
[GitCredential "azure-devops"]
Host = dev.azure.com
Protocol = https
OAuthIntegration = my-git-oauth-integration

OAuth with GitHub Apps

A GitHub App integration can serve as the credential source for Git-backed content on github.com or GitHub Enterprise Server. Connect requests an installation access token from the GitHub App and authenticates Git operations with it. The same integration type that delivers GitHub tokens to running content works here, so a GitHub App integration already configured for content needs no changes.

Step 1: Create the GitHub App and the integration

Follow the GitHub App setup instructions to create the app, generate a private key, install the app, and create the integration in Connect. Make two choices along the way that Git-backed content depends on:

  • Grant the app read access to repository contents. If you restrict the token scope with the permissions field on the integration, include contents:read.
  • Install the app on every repository that Git-backed content uses.

You need the name you gave the integration for Step 2.

Important

The GitHub App installation must cover each private repository that Git-backed content uses. Connect cannot clone a private repository outside the installation, even when the integration is otherwise valid. This is the same prerequisite that service principals have on Azure DevOps.

The installation is not an allowlist. GitHub serves public repositories to any valid token, so publishers can still use public repositories outside the installation.

Important

When creating the integration for Git, set the ACL to restrict access to administrators only. This prevents publishers from associating the Git integration with published content.

Step 2: Configure Connect

Add a GitCredential section for GitHub, setting OAuthIntegration to the name of the integration from Step 1:

/etc/rstudio-connect/rstudio-connect.gcfg
[GitCredential "github"]
Host = github.com
Protocol = https
Username = x-access-token
OAuthIntegration = my-github-app

For GitHub Enterprise Server, set Host to your server hostname instead of github.com.

Important

Hosts must be unique across GitCredential sections, so github.com can use only one integration. If you already have a GitCredential section for github.com, replace it rather than adding a second one, because two sections with the same host make Git-backed content on that host unavailable. A GitHub App integration names a single installation, and an installation covers a single GitHub organization or user account. Git-backed content on github.com therefore reaches private repositories in one organization. To reach private repositories across several organizations, configure GitCredential.Password with a personal access token that covers them.

Important

Set Username to x-access-token. GitHub expects an installation access token as the basic auth password with that username. Without Username, Connect sends a bearer token instead, which is the form Azure DevOps expects.

Step 3: Restart Connect

Restart the Connect service so it picks up the new credential:

Terminal
sudo systemctl restart rstudio-connect

If you are running Off-Host Execution, run helm upgrade with your updated configuration instead.

Publishers can then create Git-backed content from any private repository covered by the GitHub App installation. Connect requests a fresh installation access token when it clones and polls the repository, so no further credential maintenance is required.

Creating the integration for other providers

For Git hosting platforms other than Azure DevOps and GitHub, create a service account integration in Connect with the credentials from your platform. A service account integration uses the client credentials flow to obtain access tokens.

You need the following from your Git hosting platform:

  • Client ID: The application/client identifier
  • Client secret: The application secret
  • Token endpoint URL: The OAuth token endpoint for your provider
  • Scopes: The OAuth scopes required for Git operations (provider-specific)

See the Integrations documentation for details on creating integrations.

Configuring GitCredential for OAuth

Configure Connect to use the integration by setting GitCredential.OAuthIntegration to the name of your integration:

/etc/rstudio-connect/rstudio-connect.gcfg
[GitCredential "azure-devops"]
Host = dev.azure.com
Protocol = https
OAuthIntegration = my-git-oauth-integration
Important

The value of OAuthIntegration must exactly match the name you gave the integration when you created it in Connect. Connect uses this name to look up the integration and obtain access tokens for Git authentication.

Note

When using OAuth authentication, do not set GitCredential.Password. Set GitCredential.Username only when the platform expects the token as a basic auth password, as described in Setting the username.

Branch management

Publishers and administrators can change the branch for Git-backed content from the Settings > Source panel without creating a new content item. The branch dropdown is sorted with the repository’s default branch first, followed by common convention names (main, master, release/*, develop, dev), then alphabetically. If the remote repository is unreachable, users can type a branch name directly into the input field.

When a fetch error occurs, the Git Details section displays the branch name, the time of the last fetch attempt, and the most recent successful commit. This information helps diagnose connectivity or credential issues with the remote repository.

Automatic fetch & deploy

Git backed content differs from content that is directly published to Posit Connect, as indirect user actions such as pushing a Git commit to the associated repository can result in a new deployment. The decision to trigger a new deployment is made after a periodic fetch of the source repository, and only occurs if the specified branch and path prefix have changed since the last fetched commit.

Note

Periodic Git fetches are automatically performed at ~15 minute intervals for each Git backed application. This interval duration can be modified via the Git.PollingFrequency setting. To turn off automatic Git fetches entirely, set the value to 0.

Note

The same polling frequency interval and deployment logic are used for public and private repositories.

Operational considerations

Throughout the lifetime of managing Git backed content, various background processes can be spawned, and data written to file storage. As a result, the number and type of processes running on the system can vary independent of users interacting with Posit Connect. The size and composition of file based storage can likewise independently change over time.

Repository data

All Git repository clones and cached metadata are stored relative to the Server.DataDir at {Server.DataDir}/git.

Automatic cleanup

An automatic cleanup is triggered at startup time and periodically during runtime which is responsible for removing any Git repository data which is no longer in use. Such data includes Git repository clones which are not associated with content and temporary clones fetched prior to first deploy.

Concurrency limits

The Git.Concurrency setting limits the number of concurrent parent processes which can be spawned for Git operations. The limit is imposed at the individual Connect process level, meaning that a clustered deployment has a total concurrency that is a multiple of the cluster members.

Process management

Git operations are run in a process sandbox using the configured supervisor command, if any. It is particularly important to ensure that the supervisor command does not write anything to standard out, as this interferes in unpredictable ways with git operations. Supervisor scripts must echo all informational messages to standard error rather than standard out.

Requiring Git-backed publishing

By default, publishers can upload bundles directly in several ways, such as through rsconnect, rsconnect-python, and Posit Publisher. To require publishers to deploy through a Git repository instead, revoke the bundles:upload permission from the Publisher role, as described in Customizing user roles.

When the permission is revoked, Connect rejects direct bundle uploads from publishers. Publishers must use Git-backed publishing, as described in Publishing for the first time. Administrators remain exempt and can still upload bundles via any supported publishing mechanism. Revoking this permission does not prevent publishers from other content management actions such as managing content settings or changing the active bundle.

Revoking this permission does not block trusted publishing. If a content item has a trusted publisher, the matching workload, such as a GitHub Actions workflow, can still upload bundles to that content item. Like Git-backed publishing, trusted publishing deploys from a known source repository or workflow, not from a publisher’s computer. To block a workload, remove its trusted publisher from the content item. To block all trusted publishing, disable trusted publishing on the server.

Disabling

In the case that Git backed content is not desired, such as when the Git version requirement cannot be met, it can be disabled by setting Git.Enabled to false.