Skip to content

feat(github): add GitHub App authentication for self-hosted runner registration - #860

Open
adrianriobo wants to merge 1 commit into
redhat-developer:mainfrom
adrianriobo:fix-851
Open

feat(github): add GitHub App authentication for self-hosted runner registration#860
adrianriobo wants to merge 1 commit into
redhat-developer:mainfrom
adrianriobo:fix-851

Conversation

@adrianriobo

Copy link
Copy Markdown
Collaborator

Summary

  • Replaces the manual short-lived token / PAT approach with GitHub App authentication for registering self-hosted runners
  • The Pulumi GitHub provider (pulumi-github/sdk/v6) is instantiated with AppAuth inside the deployment context and calls GetActionsRegistrationToken at deploy time — no pre-generated tokens or JWT handling required
  • Backward compatible: --ghactions-runner-token (explicit token) and GITHUB_TOKEN (PAT auto-generate) both continue to work unchanged

Changes

  • pkg/integrations/github/types.go — add AppID, InstallationID, PrivateKeyPath to GithubRunnerArgs
  • pkg/integrations/github/ghrunner.go — add SetupRunner() using pulumi-github provider with AppAuth
  • pkg/integrations/github/api.go — refactor owner/repo parsing into shared helper
  • cmd/mapt/cmd/params/params.go — add --ghactions-app-id, --ghactions-app-installation-id, --ghactions-app-private-key flags
  • All 7 providers (rhel, fedora, windows-server, mac, azure-windows, ibm-power, ibm-z) — call github.SetupRunner() before user-data generation
  • go.mod / go.sum — add github.com/pulumi/pulumi-github/sdk/v6 v6.14.0
  • oci/Containerfile — install pulumi plugin resource github v6.14.0 with renovate annotation
  • docs/self-hosted-runner.md — document all three auth options (App, PAT, manual token)

Test plan

  • Build passes: make build
  • Deploy a runner using --ghactions-app-id / --ghactions-app-installation-id / --ghactions-app-private-key
  • Verify PAT path (GITHUB_TOKEN) still works
  • Verify explicit --ghactions-runner-token path still works

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Too many files!

This PR contains 205 files, which is 105 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bb09d235-f6c9-445b-ba96-1cb9d4657a4d

📥 Commits

Reviewing files that changed from the base of the PR and between 444c89f and f3c0c71.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (205)
  • cmd/mapt/cmd/aws/hosts/fedora.go
  • cmd/mapt/cmd/aws/hosts/mac.go
  • cmd/mapt/cmd/aws/hosts/rhel.go
  • cmd/mapt/cmd/aws/hosts/windows.go
  • cmd/mapt/cmd/azure/hosts/rhel.go
  • cmd/mapt/cmd/azure/hosts/windows.go
  • cmd/mapt/cmd/ibmcloud/hosts/ibm-power.go
  • cmd/mapt/cmd/ibmcloud/hosts/ibm-z.go
  • cmd/mapt/cmd/params/params.go
  • docs/self-hosted-runner.md
  • go.mod
  • oci/Containerfile
  • pkg/integrations/github/api.go
  • pkg/integrations/github/ghrunner.go
  • pkg/integrations/github/snippet-darwin.sh
  • pkg/integrations/github/snippet-linux-ppc64le.sh
  • pkg/integrations/github/snippet-linux-s390x.sh
  • pkg/integrations/github/snippet-linux.sh
  • pkg/integrations/github/snippet-windows.ps1
  • pkg/integrations/github/types.go
  • pkg/integrations/integrations.go
  • pkg/provider/aws/action/fedora/fedora.go
  • pkg/provider/aws/action/mac/mac.go
  • pkg/provider/aws/action/rhel/rhel.go
  • pkg/provider/aws/action/windows/windows.go
  • pkg/provider/aws/modules/mac/machine/setup/setup.go
  • pkg/provider/azure/action/linux/linux.go
  • pkg/provider/azure/action/windows/windows.go
  • pkg/provider/ibmcloud/action/ibm-power/ibm-power.go
  • pkg/provider/ibmcloud/action/ibm-z/ibm-z.go
  • pkg/target/host/fedora/fedora.go
  • pkg/target/host/rhel/cloud-config.go
  • pkg/target/host/windows-server/windows-server.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/LICENSE
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsEnvironmentSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsEnvironmentVariable.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsHostedRunner.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationOidcSubjectClaimCustomizationTemplate.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationPermissions.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationSecretRepositories.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationSecretRepository.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationVariable.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationVariableRepositories.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationVariableRepository.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsOrganizationWorkflowPermissions.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsRepositoryAccessLevel.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsRepositoryOidcSubjectClaimCustomizationTemplate.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsRepositoryPermissions.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsRunnerGroup.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/actionsVariable.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/appInstallationRepositories.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/appInstallationRepository.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/branch.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/branchDefault.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/branchProtection.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/branchProtectionV3.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/codespacesOrganizationSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/codespacesOrganizationSecretRepositories.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/codespacesSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/codespacesUserSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/dependabotOrganizationSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/dependabotOrganizationSecretRepositories.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/dependabotOrganizationSecretRepository.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/dependabotSecret.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/doc.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/emuGroupMapping.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/enterpriseActionsPermissions.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/enterpriseActionsRunnerGroup.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/enterpriseActionsWorkflowPermissions.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/enterpriseIpAllowListEntry.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/enterpriseOrganization.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/enterpriseSecurityAnalysisSettings.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsEnvironmentPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsEnvironmentSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsEnvironmentVariables.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsOrganizationOidcSubjectClaimCustomizationTemplate.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsOrganizationPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsOrganizationRegistrationToken.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsOrganizationSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsOrganizationVariables.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsRegistrationToken.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsRepositoryOidcSubjectClaimCustomizationTemplate.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getActionsVariables.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getAppToken.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getBranch.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getBranchProtectionRules.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getCodespacesOrganizationPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getCodespacesOrganizationSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getCodespacesPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getCodespacesSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getCodespacesUserPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getCodespacesUserSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getCollaborators.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getDependabotOrganizationPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getDependabotOrganizationSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getDependabotPublicKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getDependabotSecrets.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getEnterprise.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getExternalGroups.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getGithubApp.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getIpRanges.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getIssueLabels.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getMembership.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganization.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationAppInstallations.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationCustomProperties.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationCustomRole.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationExternalIdentities.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationIpAllowList.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationRepositoryRole.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationRepositoryRoles.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationRole.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationRoleTeams.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationRoleUsers.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationRoles.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationSecurityManagers.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationTeamSyncGroups.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationTeams.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getOrganizationWebhooks.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRef.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRelease.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getReleaseAsset.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositories.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepository.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryAutolinkReferences.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryBranches.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryCustomProperties.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryDeployKeys.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryDeploymentBranchPolicies.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryEnvironmentDeploymentPolicies.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryEnvironments.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryFile.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryMilestone.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryPages.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryPullRequest.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryPullRequests.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryTeams.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRepositoryWebhooks.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getRestApi.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getSshKeys.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getTeam.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getTree.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getUser.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getUserExternalIdentity.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/getUsers.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/init.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/internal/pulumiUtilities.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/internal/pulumiVersion.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/issue.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/issueLabel.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/issueLabels.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/membership.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationBlock.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationCustomProperties.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationCustomRole.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationProject.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationRepositoryRole.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationRole.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationRoleTeam.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationRoleTeamAssignment.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationRoleUser.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationRuleset.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationSecurityManager.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationSettings.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/organizationWebhook.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/projectCard.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/projectColumn.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/provider.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/pulumi-plugin.json
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/pulumiTypes.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/release.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repository.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryAutolinkReference.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryCollaborator.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryCollaborators.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryCustomProperty.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryDependabotSecurityUpdates.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryDeployKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryDeploymentBranchPolicy.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryEnvironment.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryEnvironmentDeploymentPolicy.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryFile.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryMilestone.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryPages.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryProject.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryPullRequest.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryRuleset.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryTopics.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryVulnerabilityAlerts.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/repositoryWebhook.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/team.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/teamMembers.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/teamMembership.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/teamRepository.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/teamSettings.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/teamSyncGroupMapping.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/userGpgKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/userInvitationAccepter.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/userSshKey.go
  • vendor/github.com/pulumi/pulumi-github/sdk/v6/go/github/workflowRepositoryPermissions.go
  • vendor/modules.txt

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Changes

GitHub Runner Authentication

Layer / File(s) Summary
GitHub App authentication inputs
cmd/mapt/cmd/params/params.go, pkg/integrations/github/types.go
Adds GitHub App flags and runner argument fields, validates required App credentials, and preserves PAT or registration-token handling.
Registration token setup
pkg/integrations/github/*, go.mod, vendor/modules.txt, oci/Containerfile
Parses repository URLs, creates a Pulumi GitHub provider, retrieves registration tokens, and installs the GitHub Pulumi plugin.
Deployment runner initialization
pkg/provider/..., pkg/target/host/...
Initializes GitHub runners before existing runner and userdata provisioning across supported deployment paths.
Authentication deployment documentation
docs/self-hosted-runner.md
Documents supported platforms and GitHub App, PAT, and pre-generated registration-token authentication options.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant SetupRunner
  participant PulumiGitHub
  participant GitHub
  participant DeploymentTarget
  CLI->>DeploymentTarget: Provide GitHub runner arguments
  DeploymentTarget->>SetupRunner: Initialize runner
  SetupRunner->>PulumiGitHub: Create App provider
  PulumiGitHub->>GitHub: Request registration token
  GitHub-->>SetupRunner: Return registration token
  SetupRunner-->>DeploymentTarget: Store token
  DeploymentTarget->>DeploymentTarget: Generate runner userdata
Loading

Suggested reviewers: anjannath, deekay2310

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding GitHub App authentication for self-hosted runner registration.
Description check ✅ Passed The description is on-topic and accurately describes the GitHub App auth changes, compatibility, and related implementation details.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
oci/Containerfile (1)

14-19: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore the vendored pulumi-github SDK

go.mod and vendor/modules.txt still reference github.com/pulumi/pulumi-github/sdk/v6, but the corresponding vendor/github.com/pulumi/pulumi-github/ sources are missing. Regenerate vendor/ and commit those files so make build can resolve imports under -mod=vendor.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@oci/Containerfile` around lines 14 - 19, Regenerate the Go vendor directory
so the pulumi-github SDK referenced by go.mod and vendor/modules.txt is restored
under vendor/github.com/pulumi/pulumi-github/, including all required source
files and metadata. Commit the regenerated vendor contents and keep the existing
make build flow unchanged.

Sources: Linters/SAST tools, Pipeline failures

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/self-hosted-runner.md`:
- Line 16: Update the authentication precedence description in the self-hosted
runner documentation to match GithubRunnerArgs: select GitHub App authentication
first, then the explicit --ghactions-runner-token value, and generate a token
from GITHUB_TOKEN only when no explicit token is supplied.
- Around line 24-25: Update the prerequisites in the self-hosted runner
documentation to describe repository-level GitHub App permissions and
installation only. Remove the organization-level permission and runner wording
from the entries associated with the --ghactions-runner-repo setup, leaving the
repository-scoped requirements unchanged.

---

Outside diff comments:
In `@oci/Containerfile`:
- Around line 14-19: Regenerate the Go vendor directory so the pulumi-github SDK
referenced by go.mod and vendor/modules.txt is restored under
vendor/github.com/pulumi/pulumi-github/, including all required source files and
metadata. Commit the regenerated vendor contents and keep the existing make
build flow unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 97347c14-74ad-4aab-8ac6-a8356f35750a

📥 Commits

Reviewing files that changed from the base of the PR and between 75a46d4 and 444c89f.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (15)
  • cmd/mapt/cmd/params/params.go
  • docs/self-hosted-runner.md
  • go.mod
  • oci/Containerfile
  • pkg/integrations/github/api.go
  • pkg/integrations/github/ghrunner.go
  • pkg/integrations/github/types.go
  • pkg/provider/aws/modules/mac/machine/setup/setup.go
  • pkg/provider/azure/action/windows/windows.go
  • pkg/provider/ibmcloud/action/ibm-power/ibm-power.go
  • pkg/provider/ibmcloud/action/ibm-z/ibm-z.go
  • pkg/target/host/fedora/fedora.go
  • pkg/target/host/rhel/cloud-config.go
  • pkg/target/host/windows-server/windows-server.go
  • vendor/modules.txt

Comment thread docs/self-hosted-runner.md Outdated
Comment thread docs/self-hosted-runner.md Outdated
@ktdreyer

Copy link
Copy Markdown

@adrianriobo , it sounds like you're picturing that something or someone would run mapt with --ghactions-app-private-key ? What is the thing that would run that?

@adrianriobo

Copy link
Copy Markdown
Collaborator Author

My ideal world would be the controller who will check events for workloads on an specific type of runner, it will run automatically mapt create to create and join the runner.

In a first phase if we define a set of static (long live) runners this will be executed either by an operator or a pipeline if we define them in a gitops approach

@ktdreyer

Copy link
Copy Markdown

Ok, thanks. gitops approach preferred.

@deekay2310 deekay2310 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a handful of nits; nothing blocking.

Comment thread pkg/integrations/github/ghrunner.go Outdated
}
args.Token = result.Token
} else {
_, repo, _ := splitOwnerRepo(args.RepoURL)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error from splitOwnerRepo is discarded here. It's technically safe today because the same URL was validated at line 135, but if the code paths are ever refactored independently this becomes a silent failure.

Suggested change
_, repo, _ := splitOwnerRepo(args.RepoURL)
_, repo, err := splitOwnerRepo(args.RepoURL)
if err != nil {
return err
}

Comment thread pkg/integrations/github/ghrunner.go Outdated
AppAuth: pulgithub.ProviderAppAuthPtr(&pulgithub.ProviderAppAuthArgs{
Id: pulumi.String(args.AppID),
InstallationId: pulumi.String(args.InstallationID),
PemFile: pulumi.String(string(pemBytes)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provider SDK's NewProvider only auto-wraps Token as a secret (see provider.go:51), not AppAuth.PemFile. This means the RSA private key will appear in plaintext in Pulumi state.

Suggested change
PemFile: pulumi.String(string(pemBytes)),
PemFile: pulumi.ToSecret(pulumi.String(string(pemBytes))).(pulumi.StringInput),

Comment thread docs/self-hosted-runner.md Outdated
"expires_at": "2024-07-12T19:01:48.478+05:30"
}
```
1. Create a GitHub App with the `administration:write` permission on the target repository.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For org-level runners (--ghactions-runner-org), the App needs the organization_self_hosted_runners:write permission instead of repo-level administration:write. Since the flags table and code already support the org path, consider something like:

Suggested change
1. Create a GitHub App with the `administration:write` permission on the target repository.
1. Create a GitHub App with the `administration:write` permission (for repository runners) or `organization_self_hosted_runners:write` permission (for organization runners).

Comment thread docs/self-hosted-runner.md Outdated
To deploy a Windows runner on the Azure provider, we can use the following command:
### Option B — Personal Access Token (PAT)

Set the `GITHUB_TOKEN` environment variable to a PAT with `repo` admin scope. `mapt` will call the GitHub API to generate a registration token automatically before deployment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only covers the repo case. For org-level runners (--ghactions-runner-org), the PAT needs admin:org scope instead of repo admin. The error message in api.go:58 already tells the user this on failure, but it'd be better to document it upfront.

Suggested change
Set the `GITHUB_TOKEN` environment variable to a PAT with `repo` admin scope. `mapt` will call the GitHub API to generate a registration token automatically before deployment.
Set the `GITHUB_TOKEN` environment variable to a PAT with `repo` scope (for repository runners) or `admin:org` scope (for organization runners). `mapt` will call the GitHub API to generate a registration token automatically before deployment.

…tion

Adds GitHub App authentication for self-hosted runner registration and
deregisters runners from the GitHub API at destroy time — replacing an
earlier attempt that tried to call config.sh remove from inside the VM
(config.sh remove always prompts for a fresh removal token; stored
registration credentials cannot be reused).

## Registration (create)

- Add GitHub App auth path: RS256 JWT generation via stdlib crypto
  (PKCS1 and PKCS8), exchanged for a short-lived installation access
  token. PAT (GITHUB_TOKEN) remains supported.
- Add --ghactions-app-id, --ghactions-app-installation-id,
  --ghactions-app-private-key flags to all create commands.
- Add --ghactions-runner-ephemeral flag to control runner lifetime.
- Add org-level runner support via --ghactions-runner-org.
- Add ppc64le/s390x fallback to the built layout when the vm.sh test
  step fails.

## Deregistration (destroy)

- ExportRunnerOutputs persists runner name + org/repo URL as Pulumi
  stack outputs at create time.
- Destroy reads stack outputs, calls GetManagementToken (App JWT or
  GITHUB_TOKEN) + TryDeregister (GitHub API list + delete by name)
  before tearing down the stack. Best-effort: failures are logged as
  warnings so destroy always proceeds.
- GithubRunnerDeregisterArgs: returns minimal credentials for destroy
  without consuming a one-time registration token.
- --ghactions-app-* flags exposed on all destroy commands.
- Covered targets: IBM Z, IBM Power, AWS RHEL, AWS Fedora, AWS Windows,
  AWS Mac, Azure RHEL, Azure Windows.

## Fixes (review nits)

- Handle splitOwnerRepo error in SetupRunner instead of discarding it.
- Mark AppAuth.PemFile as a Pulumi secret so the RSA key does not
  appear in plaintext in state.
- docs/self-hosted-runner.md: document org vs repo App permissions
  (administration:write vs organization_self_hosted_runners:write) and
  PAT scopes (repo vs admin:org).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@deekay2310

Copy link
Copy Markdown
Contributor

Tested the GitHub App authentication path on IBM Power VS (ibmcloud ibm-power create).

What was tested:

  • Deployed a ppc64le self-hosted runner using --ghactions-app-id, --ghactions-app-installation-id, and --ghactions-app-private-key flags
  • Runner registered successfully to the opendatahub-io-contrib org with labels ppc64le,ibmcloud,self-hosted
  • Connection details (bastion host, SSH keys, target host) were output correctly to the workspace directory

Smoke test runs (both passed):

Config used:

  • Image: ghcr.io/redhat-developer/mapt:pr-860
  • Region: us-south / Zone: dal14
  • State backend: S3 bucket (mapt-test-bucket-evidence)

@deekay2310

Copy link
Copy Markdown
Contributor

Also tested the GitHub App authentication path on IBM Z (ibmcloud ibm-z create).

What was tested:

  • Deployed an s390x self-hosted runner using --ghactions-app-id, --ghactions-app-installation-id, and --ghactions-app-private-key flags
  • Runner registered successfully to the opendatahub-io-contrib org with labels s390x,ibmcloud,self-hosted
  • Connection details (host, SSH key, username) were output correctly to the workspace directory

Smoke test run (passed):

Note: First run failed due to /etc/gitconfig having restrictive permissions (not related to this PR — cloud-init sets it to root-only). Fixed by chmod 644 /etc/gitconfig, second run passed clean.

Config used:

  • Image: ghcr.io/redhat-developer/mapt:pr-860
  • Region: us-south / Zone: us-south-2
  • Subnet: aipcc-productization-glab-runners-dal
  • State backend: S3 bucket (mapt-test-bucket-evidence)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants