-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC-007] Implement GitHub app authentication for git repositories. #1647
base: main
Are you sure you want to change the base?
Conversation
2ada071
to
0e437a3
Compare
Thank you for picking up this topic. Can we also add documentation for the use with GitHub Enterprise? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did some basic testing and it worked as expected for the happy path
spec:
interval: 5m0s
provider: github
ref:
branch: main
secretRef:
name: github-sa
timeout: 60s
url: https://github.com/darkowlzz/test-1
status:
artifact:
digest: sha256:4166a3310c4f57471a5cfa2910475e4d47874920d7c156f656b7e70c01adcd2e
lastUpdateTime: "2024-12-03T21:09:21Z"
path: gitrepository/default/test-1/a4f6eca644dadd9112ff3d93c99eda63eeca949a.tar.gz
revision: main@sha1:a4f6eca644dadd9112ff3d93c99eda63eeca949a
size: 4083
url: http://:0/gitrepository/default/test-1/a4f6eca644dadd9112ff3d93c99eda63eeca949a.tar.gz
conditions:
- lastTransitionTime: "2024-12-03T21:09:21Z"
message: stored artifact for revision 'main@sha1:a4f6eca644dadd9112ff3d93c99eda63eeca949a'
observedGeneration: 1
reason: Succeeded
status: "True"
type: Ready
- lastTransitionTime: "2024-12-03T21:09:21Z"
message: stored artifact for revision 'main@sha1:a4f6eca644dadd9112ff3d93c99eda63eeca949a'
observedGeneration: 1
reason: Succeeded
status: "True"
type: ArtifactInStorage
observedGeneration: 1
Left some comments, suggestions a few improvements.
AzureOpts: []azure.OptFunc{ | ||
azure.WithAzureDevOpsScope(), | ||
}, | ||
} | ||
case sourcev1.GitProviderGitHub: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike Azure, GitHub provider requires a secret reference containing the identity details. Currently, not providing any secret ref results in the following state:
status:
conditions:
- lastTransitionTime: "2024-12-03T21:11:55Z"
message: building artifact
observedGeneration: 1
reason: ProgressingWithRetry
status: "True"
type: Reconciling
- lastTransitionTime: "2024-12-03T21:11:55Z"
message: 'failed to checkout and determine revision: invalid app id, err: strconv.Atoi:
parsing "": invalid syntax'
observedGeneration: 1
reason: GitOperationFailed
status: "False"
type: Ready
- lastTransitionTime: "2024-12-03T21:11:50Z"
message: 'failed to checkout and determine revision: invalid app id, err: strconv.Atoi:
parsing "": invalid syntax'
observedGeneration: 1
reason: GitOperationFailed
status: "True"
type: FetchFailed
observedGeneration: -1
and similar logs
{"level":"error","ts":"2024-12-04T02:42:13.583+0530","msg":"Reconciler error","controller":"gitrepository","controllerGroup":"source.toolkit.fluxcd.io","controllerKind":"GitRepository","GitRepository":{"name":"test-1","namespace":"default"},"namespace":"default","name":"test-1","reconcileID":"eaa78267-8c4a-4d85-9779-05226fff0b2b","error":"failed to checkout and determine revision: invalid app id, err: strconv.Atoi: parsing \"\": invalid syntax"}
I don't think these are friendly enough for the new users. Also, this is a bad configuration and should result in Stalled state.
❗ NOTE: The following suggestion can be ignored. See the next comment for another suggestion with considerations of more scenarios.
getAuthOpts()
returns error that's interpreted as a generic error to attempt a retry. Rather than trying to return a typed error from getAuthOpts()
and then try to return the appropriate error, it may be better to create a new function for just validating the provider related configuration (just for GitHub for now, but GitLab too in the future) and any error returned from it should result in a stalling error. We can call this function just before
authOpts, err := r.getAuthOpts(ctx, obj, *u) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was discussed in the dev meeting today and we have two more scenarios related to this that should have validation:
- When a secret ref is provided but the provider is not set, and the secret contains github app data, it should result in a stalling failure with error saying that the secret contains github app data, please set the provider to github. It may be better to first check if the repository host is github.com before checking the secret.
- When a secret ref is provided and the provider is set to github, but the secret does not contain github app data fields, it should result in a retryable failure (generic error) with error saying that the secret must have the github app data. This is a validation of the provided secret content. Because we don't watch the secret, we don't have a way to get notified when the secret is fixed. We have to fail and retry, hoping that eventually the secret will be fixed.
With this, I'd backtrack a bit. Initially, I was recommending to validate that the secret ref is provided when github is the provider before getAuthOpts()
as there was no secret involved. But with the two scenarios above, the secret content needs to be analyzed. It would be better to get the secret just once, which we already have in getAuthOpts()
.
I think we can change getAuthOpts()
similar to the other functions, like verifySignature()
, fetchIncludes()
and others where the errors and conditions are set within these functions. The caller just returns the result. That way, we remain consistent with what's done in other functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improved the error messaging for the following 4 scenarios, added unit tests and tested with SC.
- Provider:
github
, nosecretRef
ingitRepository
spec
Result: Stalling error, error message: secretRef with github app data must be specified when provider is set to github
Name: ghapp-repo
Namespace: default
Labels: <none>
Annotations: <none>
API Version: source.toolkit.fluxcd.io/v1
Kind: GitRepository
Metadata:
Creation Timestamp: 2024-12-05T20:24:11Z
Finalizers:
finalizers.fluxcd.io
Generation: 1
Resource Version: 17094229
UID: 67a75e2e-55f6-4e60-bb04-187e0698a5bb
Spec:
Interval: 1m
Provider: github
Ref:
Branch: main
Timeout: 60s
URL: https://github.com/dp-flux-testing/dp-flux-testing.git
Status:
Conditions:
Last Transition Time: 2024-12-05T20:24:11Z
Message: secretRef with github app data must be specified when provider is set to github
Observed Generation: 1
Reason: AuthenticationFailed
Status: True
Type: Stalled
Last Transition Time: 2024-12-05T20:24:11Z
Message: secretRef with github app data must be specified when provider is set to github
Observed Generation: 1
Reason: AuthenticationFailed
Status: False
Type: Ready
Last Transition Time: 2024-12-05T20:24:11Z
Message: secretRef with github app data must be specified when provider is set to github
Observed Generation: 1
Reason: AuthenticationFailed
Status: True
Type: FetchFailed
Observed Generation: 1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning AuthenticationFailed 28s source-controller secretRef with github app data must be specified when provider is set to github
- provider:
github
,secretRef
is present, but secret is not present
Result: Generic error with retry.
Name: ghapp-repo
Namespace: default
Labels: <none>
Annotations: <none>
API Version: source.toolkit.fluxcd.io/v1
Kind: GitRepository
Metadata:
Creation Timestamp: 2024-12-05T20:24:11Z
Finalizers:
finalizers.fluxcd.io
Generation: 2
Resource Version: 17095637
UID: 67a75e2e-55f6-4e60-bb04-187e0698a5bb
Spec:
Interval: 1m
Provider: github
Ref:
Branch: main
Secret Ref:
Name: ghapp-secret
Timeout: 60s
URL: https://github.com/dp-flux-testing/dp-flux-testing.git
Status:
Conditions:
Last Transition Time: 2024-12-05T20:29:13Z
Message: building artifact
Observed Generation: 2
Reason: ProgressingWithRetry
Status: True
Type: Reconciling
Last Transition Time: 2024-12-05T20:29:13Z
Message: failed to get secret 'default/ghapp-secret': secrets "ghapp-secret" not found
Observed Generation: 2
Reason: AuthenticationFailed
Status: False
Type: Ready
Last Transition Time: 2024-12-05T20:29:02Z
Message: failed to get secret 'default/ghapp-secret': secrets "ghapp-secret" not found
Observed Generation: 2
Reason: AuthenticationFailed
Status: True
Type: FetchFailed
Observed Generation: 1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning AuthenticationFailed 5m9s source-controller secretRef with github app data must be specified when provider is set to github
Warning AuthenticationFailed 7s (x5 over 18s) source-controller failed to get secret 'default/ghapp-secret': secrets "ghapp-secret" not found
- provider:
github
, associated secret has missing app ID/app Installation ID/private key.
Result: Generic error, validation in pkg code during checkout.
Name: ghapp-repo
Namespace: default
Labels: <none>
Annotations: <none>
API Version: source.toolkit.fluxcd.io/v1
Kind: GitRepository
Metadata:
Creation Timestamp: 2024-12-05T20:24:11Z
Finalizers:
finalizers.fluxcd.io
Generation: 2
Resource Version: 17097352
UID: 67a75e2e-55f6-4e60-bb04-187e0698a5bb
Spec:
Interval: 1m
Provider: github
Ref:
Branch: main
Secret Ref:
Name: ghapp-secret
Timeout: 60s
URL: https://github.com/dp-flux-testing/dp-flux-testing.git
Status:
Conditions:
Last Transition Time: 2024-12-05T20:35:25Z
Message: building artifact
Observed Generation: 2
Reason: ProgressingWithRetry
Status: True
Type: Reconciling
Last Transition Time: 2024-12-05T20:35:25Z
Message: failed to checkout and determine revision: private key must be provided to use github app authentication
Observed Generation: 2
Reason: GitOperationFailed
Status: False
Type: Ready
Last Transition Time: 2024-12-05T20:35:25Z
Message: failed to checkout and determine revision: private key must be provided to use github app authentication
Observed Generation: 2
Reason: GitOperationFailed
Status: True
Type: FetchFailed
Observed Generation: 1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning AuthenticationFailed 13m source-controller secretRef with github app data must be specified when provider is set to github
Warning AuthenticationFailed 7m43s (x7 over 8m30s) source-controller failed to get secret 'default/ghapp-secret': secrets "ghapp-secret" not found
Warning GitOperationFailed 6m55s source-controller failed to checkout and determine revision: app ID must be provided to use github app authentication
Warning GitOperationFailed 5m19s source-controller failed to checkout and determine revision: app installation ID must be provided to use github app authentication
Warning GitOperationFailed 2m7s source-controller failed to checkout and determine revision: private key must be provided to use github app authentication
- secret contains githubAppID and provider not set.
Result: Stalling error indicating provider is not set to github
Notes:
- As discussed in the dev meeting, checking only for github App ID presence to detect that intent is to use github app authentication.
- Did not include hostname validation here since for Github Enterprise Server, the hostname does not necessarily contain 'github'. In any case the
secret
should not contain githubAppID as data unless intent was to use github app authentication. Let me know thoughts.
Name: ghapp-repo
Namespace: default
Labels: <none>
Annotations: <none>
API Version: source.toolkit.fluxcd.io/v1
Kind: GitRepository
Metadata:
Creation Timestamp: 2024-12-05T20:24:11Z
Finalizers:
finalizers.fluxcd.io
Generation: 3
Resource Version: 17099528
UID: 67a75e2e-55f6-4e60-bb04-187e0698a5bb
Spec:
Interval: 1m
Ref:
Branch: main
Secret Ref:
Name: ghapp-secret
Timeout: 60s
URL: https://github.com/dp-flux-testing/dp-flux-testing.git
Status:
Artifact:
Digest: sha256:312bafaed0040134c57615608de187def57d97d4db09e46a3d64562b6f9c96ed
Last Update Time: 2024-12-05T20:41:50Z
Path: gitrepository/default/ghapp-repo/f3e6c65b2ae4e0f333cf317143b20efcc83400a0.tar.gz
Revision: main@sha1:f3e6c65b2ae4e0f333cf317143b20efcc83400a0
Size: 470
URL: http://source-controller.source-system.svc.cluster.local./gitrepository/default/ghapp-repo/f3e6c65b2ae4e0f333cf317143b20efcc83400a0.tar.gz
Conditions:
Last Transition Time: 2024-12-05T20:43:18Z
Message: secretRef 'default/ghapp-secret' has github app data but provider is not set to github
Observed Generation: 3
Reason: AuthenticationFailed
Status: True
Type: Stalled
Last Transition Time: 2024-12-05T20:43:18Z
Message: secretRef 'default/ghapp-secret' has github app data but provider is not set to github
Observed Generation: 3
Reason: AuthenticationFailed
Status: False
Type: Ready
Last Transition Time: 2024-12-05T20:43:18Z
Message: secretRef 'default/ghapp-secret' has github app data but provider is not set to github
Observed Generation: 3
Reason: AuthenticationFailed
Status: True
Type: FetchFailed
Last Transition Time: 2024-12-05T20:41:50Z
Message: stored artifact for revision 'main@sha1:f3e6c65b2ae4e0f333cf317143b20efcc83400a0'
Observed Generation: 2
Reason: Succeeded
Status: True
Type: ArtifactInStorage
Observed Generation: 3
0e437a3
to
8e06af4
Compare
@dipti-pai please rebase with main, it contains the latest auth and git packages with GitHub App support. |
8e06af4
to
1c25389
Compare
- API change to add new `github` provider field in `GitRepository` spec. - Controller change to use the GitHub authentication information specified in `.spec.secretRef` to create the auth options to authenticate to git repositories when the `provider` field is set to `github`, - Tests for new `github` provider field - Updated docs to use GitHub Apps for authentication in source-controller. Signed-off-by: Dipti Pai <[email protected]>
1c25389
to
58ebb1b
Compare
github
provider field inGitRepository
spec..spec.secretRef
to create the auth options to authenticate to git repositories when theprovider
field is set togithub
github
provider field