Skip to content

feat: GitHub App authentication - #43

Merged
alpoi merged 2 commits into
masterfrom
feat/github-app-auth
Oct 28, 2026
Merged

alpoi merged 2 commits into
masterfrom
feat/github-app-auth

Conversation

@alpoi

@alpoi alpoi commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Lets the plugin authenticate as a GitHub App installation as an alternative to a token. Organizations can govern apps centrally, and the plugin only holds short-lived installation tokens, which ghinstallation renews as they expire.

This re-implements #3 by @gusfcarvalho, which has conflicts with master. Since then, go-github has moved from v71 to v93 and the plugin gained a GraphQL client. The config keys are unchanged from #3:

plugins:
  github_repos:
    app_id: "123456"
    installation_id: "78901234"
    private_key_file: /etc/ccf/github-app.pem   # or private_key: <PEM or base64 PEM>
    organization: octocat

Changes

  • auth.go: AuthConfig (embedded in PluginConfig with mapstructure:",squash", so the keys stay flat), validation, and one authenticated http.Client that backs both the REST and the GraphQL client.
  • token still takes precedence when set, so existing configs behave exactly as before.

Differences from #3

  • Validation names the missing keys (for example GitHub App authentication needs installation_id), and rejects setting both private_key_file and private_key.
  • private_key accepts plain PEM as well as base64-encoded PEM.
  • The GraphQL client (added since feat: introduces github app authentication #3) also authenticates as the app.
  • Tests: validation, the token, file, base64 and PEM paths, bad input, and decoding of the agent's flat config map.
  • README: a GitHub App section, with setup steps.

Wiring

  • gRPC round trip: auth_grpc_test.go sends Configure through go-plugin's in-process gRPC harness (TestPluginGRPCConn with runner.RunnerV2GRPCPlugin), the same path the agent uses. The agent sends config as a flat map<string, string>, and the plugin decodes it after the gRPC hop, so the embedded AuthConfig (mapstructure:",squash") never affects the wire format. The tests cover the token-only config every deployment sends today, an app config with the empty keys agent configs declare, and incomplete app credentials. Without squash they fail.
  • local-dev: compliance-framework/local-dev#135 declares the app keys in the showcase agent config (the agent only fills keys the file declares from CCF_* environment variables) and teaches the demo-go-check-github pre-flight about app credentials.

Testing

  • go vet ./... and go test ./... pass.
  • golangci-lint v2.11.4 with the shared config reports nothing in the changed files. The six warnings it prints (deprecated GetSBOM / github.Ptr, one QF1002) are already on master.
  • I haven't run it against a real GitHub App installation.

Closes #3.

🤖 Generated with Claude Code

Besides a token, the plugin can now authenticate as a GitHub App installation
(app_id, installation_id, and private_key_file or private_key), using
short-lived installation tokens that ghinstallation renews. The same HTTP
client backs the REST and GraphQL clients. A token still wins when set, so
existing configs are unaffected.

Re-implements #3 on the current master (go-github v93, the GraphQL client),
adding validation of partial app credentials, plain-PEM inline keys, tests
and docs.

Co-authored-by: Gustavo Carvalho <gustavo@externalsecrets.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 771cf931-4776-4ffd-86c9-c37de58b6194
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

gusfcarvalho
gusfcarvalho previously approved these changes Oct 28, 2026
Comment thread main.go
The agent sends plugin config over gRPC as a flat map<string, string>, which
the plugin decodes into PluginConfig with the embedded, squashed AuthConfig.
These tests send Configure through go-plugin's in-process gRPC harness: the
token config every deployment sends today, a GitHub App config (with the
empty keys agent configs declare for environment injection), and incomplete
app credentials.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alpoi added a commit to compliance-framework/plugin-dependabot that referenced this pull request Oct 28, 2026
## Summary

Lets the plugin authenticate as a **GitHub App installation** as an
alternative to a token. Organizations can govern apps centrally, and the
plugin only holds short-lived installation tokens, which
[ghinstallation](https://github.com/bradleyfalzon/ghinstallation) renews
as they expire.

This is the same change as
compliance-framework/plugin-github-repositories#43, which re-implements
@gusfcarvalho's compliance-framework/plugin-github-repositories#3. It
uses the same config keys:

```yaml
plugins:
  dependabot:
    config:
      app_id: "123456"
      installation_id: "78901234"
      private_key_file: /etc/ccf/github-app.pem   # or private_key: <PEM or base64 PEM>
      organization: octocat
```

## Changes

- `auth.go`: `AuthConfig` is embedded in `PluginConfig`
(`mapstructure:",squash"`, so the keys stay flat) and carried on
`ParsedConfig.Auth`, which replaces `ParsedConfig.Token`. It validates
the credentials and builds the authenticated `http.Client` behind the
go-github client.
- Behaviour for existing configs is unchanged:
  - `token` still wins when set.
- With no credentials at all, the plugin still calls GitHub
unauthenticated, as before.
- Only *incomplete* app credentials are a `Configure` error (for example
`GitHub App authentication needs installation_id`).
- `main_integration_test.go`: the `PluginConfig` literals now set
`AuthConfig{Token: ...}`.
- Tests for validation, the token, file, base64 and PEM paths, bad
input, and decoding of the agent's flat config map. README: an
authentication section with a GitHub App setup guide.

- **Underscores, not hyphens,** unlike `included-repositories` and the
plugin's other keys. The agent fills plugin config from `CCF_*`
environment variables by uppercasing the key and replacing dots only, so
a hyphenated `app-id` would need `CCF_PLUGINS_DEPENDABOT_CONFIG_APP-ID`,
which shells can't set. local-dev and the hosted demo pass credentials
this way, for example `CCF_PLUGINS_DEPENDABOT_CONFIG_PRIVATE_KEY`. The
README notes this.

## Wiring

- **gRPC round trip:** `auth_grpc_test.go` sends `Configure` through
go-plugin's in-process gRPC harness (`TestPluginGRPCConn` with
`runner.RunnerV2GRPCPlugin`), the same path the agent uses. The agent
sends config as a flat `map<string, string>`, and the plugin decodes it
after the gRPC hop, so the embedded `AuthConfig`
(`mapstructure:",squash"`) never affects the wire format. The tests
cover the token-only config every deployment sends today, an app config
with the empty keys agent configs declare, and incomplete app
credentials. Without `squash` they fail.
- **local-dev:** compliance-framework/local-dev#135 declares the app
keys in the showcase agent config (the agent only fills keys the file
declares from `CCF_*` environment variables) and teaches the
`demo-go-check-github` pre-flight about app credentials.

## Testing

- `go vet ./...`, `go vet -tags integration ./...` and `go test ./...`
pass.
- golangci-lint v2.11.4 with the shared config reports nothing in the
changed lines. The seven warnings it prints are already on `main`.
- I haven't run it against a real GitHub App installation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Gustavo Carvalho <gustavo@externalsecrets.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
alpoi added a commit to compliance-framework/plugin-github-settings that referenced this pull request Oct 28, 2026
## Summary

Lets the plugin authenticate as a **GitHub App installation** as an
alternative to a token. Organizations can govern apps centrally, and the
plugin only holds short-lived installation tokens, which
[ghinstallation](https://github.com/bradleyfalzon/ghinstallation) renews
as they expire.

This is the same change as
compliance-framework/plugin-github-repositories#43, which re-implements
@gusfcarvalho's compliance-framework/plugin-github-repositories#3. The
config keys are the same:

```yaml
plugins:
  github:
    config:
      app_id: "123456"
      installation_id: "78901234"
      private_key_file: /etc/ccf/github-app.pem   # or private_key: <PEM or base64 PEM>
      organization: test-org
```

## Changes

- `auth.go`: `AuthConfig` (embedded in `PluginConfig` with
`mapstructure:",squash"`, so the keys stay flat), validation, and the
authenticated `http.Client` behind the go-github client. That client
also carries the IP allow-list GraphQL query.
- `Validate` now accepts a token *or* complete app credentials, and
names any missing key (for example `GitHub App authentication needs
installation_id`). `token` still wins when set, so existing configs
behave as before.
- Tests for validation, the token, file, base64 and PEM paths, bad
input, and decoding of the agent's flat config map. README: a GitHub App
section.
- IP allow-list collection can't work with app tokens; GitHub doesn't
allow it, as the README already said. The new section repeats that next
to the app settings.

## Wiring

- **gRPC round trip:** `auth_grpc_test.go` sends `Configure` through
go-plugin's in-process gRPC harness (`TestPluginGRPCConn` with
`runner.RunnerV2GRPCPlugin`), the same path the agent uses. The agent
sends config as a flat `map<string, string>`, and the plugin decodes it
after the gRPC hop, so the embedded `AuthConfig`
(`mapstructure:",squash"`) never affects the wire format. The tests
cover the token-only config every deployment sends today, an app config
with the empty keys agent configs declare, and incomplete app
credentials. Without `squash` they fail.
- **local-dev:** compliance-framework/local-dev#135 declares the app
keys in the showcase agent config (the agent only fills keys the file
declares from `CCF_*` environment variables) and teaches the
`demo-go-check-github` pre-flight about app credentials.

## Testing

- `go vet ./...` and `go test ./...` pass.
- golangci-lint v2.11.4 with the shared config reports 0 issues.
- I haven't run it against a real GitHub App installation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Gustavo Carvalho <gustavo@externalsecrets.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@alpoi
alpoi merged commit 65774a2 into master Oct 28, 2026
24 checks passed
@alpoi
alpoi deleted the feat/github-app-auth branch October 28, 2026 15:13
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.

2 participants