Trusted publishing

Trusted publishing lets you authorize an external CI/CD workload – usually a GitHub Actions run or GitLab CI/CD pipeline – to publish a specific content item without storing a long-lived Posit Connect API key as a pipeline secret.

Note

Trusted publishing is enabled by default, but your administrator can disable it on the server.

Requirements

Before you begin:

  • Trusted publishing must be enabled on the server. It is enabled by default, but an administrator can disable it.
  • The content item must already exist in Connect. Trusted publishing authorizes an existing item; it does not create one.
  • You must be the content’s owner or a collaborator who can change its settings.
  • Your pipeline platform must be able to issue an OpenID Connect identity token (for example, GitHub Actions with id-token: write permission, or a GitLab CI/CD ID token).

Supported providers

A trusted publisher is described by a publisher type that tells Connect how the workload proves its identity. Supported providers include:

  • GitHub Actions
  • GitHub Enterprise Server
  • GitLab CI/CD
  • Custom OpenID Connect

Authorize a publisher for your content

Add a trusted publisher from the content’s settings:

  1. Open the content item and go to its Access settings.
  2. In the Trusted Publishing section, select Add Trusted Publisher.
  3. Choose the Publisher type that matches your pipeline (for example, GitHub Actions).
  4. Fill in the required fields.
  5. Optionally, enter a Name to identify the publisher more clearly.
  6. Select Add.

The publisher then appears in the Trusted Publishing list. Connect reuses an existing identity that matches the same workload when one is present, so adding the same workload again updates the existing entry rather than creating a duplicate.

Warning

A trusted publisher can publish to your content whenever its workload runs. In practice, this means that anyone who can push to the authorized repository or run its pipeline can publish to this content item. Authorize only repositories and projects you trust, and scope the configuration as narrowly as your provider allows.

GitHub Actions: immutable subject claims

GitHub repositories created on or after July 15, 2026, use immutable subject claims by default in their Actions OpenID Connect (OIDC) tokens. Older repositories can opt in to this format in the repository’s Settings > Actions > General page.

With immutable claims, the sub (subject) claim in the OIDC token embeds numeric IDs alongside human-readable names, delimited by @. For example, instead of:

repo:my-org/my-repo:ref:refs/heads/main

the token contains:

repo:my-org@123456/my-repo@789012:ref:refs/heads/main

When you configure a GitHub Actions trusted publisher in Connect, the subject claim values you enter must match the format your repository actually produces. If your repository uses immutable claims, enter the subject values with the @<id> suffixes included.

Finding your repository’s immutable identifiers

If you have the GitHub CLI installed and are authenticated, you can retrieve the identifiers for a repository:

# From within a local clone of the repository:
gh api "repos/$(gh repo view --json nameWithOwner -q .nameWithOwner)" \
  --jq '"\(.owner.login)@\(.owner.id)/\(.name)@\(.id)"'

# Or, for any repository by name:
gh api "repos/$ORG/$REPO" \
  --jq '"\(.owner.login)@\(.owner.id)/\(.name)@\(.id)"'

This prints the owner and repository in the immutable format (for example, my-org@123456/my-repo@789012). Use these values when filling in the trusted publisher fields in Connect.

Note

Connect cannot resolve these identifiers for you because it does not hold credentials to the GitHub API.

Troubleshooting

If your trusted publisher configuration looks correct but publishing fails with an HTTP 400 error at the token-exchange step, the most likely cause is a mismatch between the subject claim format your repository produces and the values configured in Connect. Verify whether your repository uses immutable subject claims and update your publisher configuration accordingly.

Publish from your CI workflow

Once a publisher is authorized, your pipeline publishes in three steps:

  1. The pipeline obtains an OIDC identity token from its platform, requesting the audience you configured (connect by default).
  2. The pipeline exchanges that token at Connect’s OAuth token endpoint for a short-lived access token. Connect verifies the token against the provider and confirms it matches an authorized publisher.
  3. The pipeline uses the access token as its Connect credential to upload a bundle and deploy the content.

The access token is valid for about an hour and can only act on the content you authorized.

Posit maintains a dedicated GitHub Action that handles most of these steps for you. It can be used as follows:

.github/workflows/publish.yml
name: publish

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@v6
      - name: Deploy to Connect
        uses: posit-dev/connect-actions/deploy@main

Remove a publisher

To revoke a publisher, open the content’s Access settings, find it in the Trusted Publishing list, and select the remove button next to it. The workload can no longer obtain an access token for this content once it is removed.