-
Notifications
You must be signed in to change notification settings - Fork 32
feat!: Vela OIDC provider #1120
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
Merged
Merged
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
e910998
init commit
ecrupper 9a35107
some renaming and comment fixing
ecrupper a089ee2
tests and renaming things here and there, plus pull in types
ecrupper e99d1c3
update subject
ecrupper a2ef469
integration test
ecrupper 095208a
Merge branch 'main' into feat/oidc-provider
ecrupper ebc9518
Merge branch 'main' into feat/oidc-provider
ecrupper 9b451c6
pull in types and add event to subject
ecrupper 9be3a5a
address lint review feedback
ecrupper 43cae89
fix tests
ecrupper 7c605ab
more integration test fixes
ecrupper a595daf
bytes buffer for exponent
ecrupper 5582b26
correct issuer and add commands claim
ecrupper 396396c
Merge branch 'main' into feat/oidc-provider
ecrupper a7d8b9b
sender to actor
ecrupper ab20991
Merge branch 'feat/oidc-provider' of github.com:go-vela/server into f…
ecrupper 75770cd
use lestrrat jwx lib for jwks
ecrupper e974df9
fixes
ecrupper 34d115f
more fixes
ecrupper e5b9af2
use wrapper for swagger jwk set
ecrupper 9d6aeb1
address feedback
ecrupper ce82c32
enhance: add build_id and actor_id to claims
plyr4 a82dd61
enhance: complete adding build_id and actor_id to claims
plyr4 5e88941
enhance: complete adding build_id and actor_id to claims
plyr4 0699f60
fix: apply context to GenerateRSA
plyr4 169b103
fix: add err check to ParseBool
plyr4 3f46a1b
enhance: audience validation
plyr4 8eed526
enhance: better audience validation
plyr4 ae353bf
enhance: add query parameter input validation
plyr4 36983c6
tweak: order of operations, move sanitize lower
plyr4 32861c6
enhance: add scm user id to build obj
plyr4 a8958cf
enhance: add GetUserID to scm interface
plyr4 242ebf9
fix: apply missing scm id using scm client lookups
plyr4 27f52be
chore: merge with main scm user id
plyr4 7625a96
chore: verbose comment on fallback user fetch
plyr4 a04a62f
Merge branch 'enhance/build-sender-id' of github.com:go-vela/server i…
plyr4 82c8578
chore: comment typo
plyr4 3d50f56
Merge branch 'enhance/build-sender-id' of github.com:go-vela/server i…
plyr4 167c95b
enhance: use repo owner token in schedule processing
plyr4 37d5dfc
enhance: use repo owner token in restart build
plyr4 4ad8f5a
Merge branch 'enhance/build-sender-id' of github.com:go-vela/server i…
plyr4 4d69c9b
enhance: change claims actor_id to actor_scm_id
plyr4 922ffd0
chore: merge with main
plyr4 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package admin | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "net/http" | ||
|
|
||
| "github.com/gin-gonic/gin" | ||
| "github.com/sirupsen/logrus" | ||
|
|
||
| "github.com/go-vela/server/database" | ||
| "github.com/go-vela/server/util" | ||
| ) | ||
|
|
||
| // swagger:operation POST /api/v1/admin/rotate_oidc_keys admin AdminRotateOIDCKeys | ||
| // | ||
| // Rotate RSA Keys | ||
| // | ||
| // --- | ||
| // produces: | ||
| // - application/json | ||
| // parameters: | ||
| // security: | ||
| // - ApiKeyAuth: [] | ||
| // responses: | ||
| // '200': | ||
| // description: Successfully rotated OIDC provider keys | ||
| // schema: | ||
| // type: string | ||
| // '500': | ||
| // description: Error unable to rotate OIDC provider keys | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
|
|
||
| // RotateOIDCKeys represents the API handler to | ||
| // rotate RSA keys in OIDC provider service. | ||
| func RotateOIDCKeys(c *gin.Context) { | ||
| logrus.Info("Admin: rotating keys for OIDC provider") | ||
|
|
||
| // capture middleware values | ||
| ctx := c.Request.Context() | ||
|
|
||
| err := database.FromContext(c).RotateKeys(ctx) | ||
| if err != nil { | ||
| retErr := fmt.Errorf("unable to rotate keys: %w", err) | ||
| util.HandleError(c, http.StatusInternalServerError, retErr) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| c.JSON(http.StatusOK, "keys rotated successfully") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package build | ||
|
|
||
| import ( | ||
| "errors" | ||
| "fmt" | ||
| "net/http" | ||
| "strconv" | ||
| "time" | ||
|
|
||
| "github.com/gin-gonic/gin" | ||
| "github.com/sirupsen/logrus" | ||
|
|
||
| "github.com/go-vela/server/constants" | ||
| "github.com/go-vela/server/internal/token" | ||
| "github.com/go-vela/server/router/middleware/build" | ||
| "github.com/go-vela/server/router/middleware/claims" | ||
| "github.com/go-vela/server/util" | ||
| "github.com/go-vela/types/library" | ||
| ) | ||
|
|
||
| // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_request_token builds GetIDRequestToken | ||
| // | ||
| // Get a Vela OIDC request token associated with a build | ||
| // | ||
| // --- | ||
| // produces: | ||
| // - application/json | ||
| // parameters: | ||
| // - in: path | ||
| // name: repo | ||
| // description: Name of the repo | ||
| // required: true | ||
| // type: string | ||
| // - in: path | ||
| // name: org | ||
| // description: Name of the org | ||
| // required: true | ||
| // type: string | ||
| // - in: path | ||
| // name: build | ||
| // description: Build number | ||
| // required: true | ||
| // type: integer | ||
| // - in: query | ||
| // name: image | ||
| // description: Add image to token claims | ||
| // type: string | ||
| // - in: query | ||
| // name: request | ||
| // description: Add request input to token claims | ||
| // type: string | ||
| // - in: query | ||
| // name: commands | ||
| // description: Add commands input to token claims | ||
| // type: boolean | ||
| // security: | ||
| // - ApiKeyAuth: [] | ||
| // responses: | ||
| // '200': | ||
| // description: Successfully retrieved ID Request token | ||
| // schema: | ||
| // "$ref": "#/definitions/Token" | ||
| // '400': | ||
| // description: Bad request | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
| // '401': | ||
| // description: Unauthorized request | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
| // '404': | ||
| // description: Unable to find build | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
| // '500': | ||
| // description: Unable to generate ID request token | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
|
|
||
| // GetIDRequestToken represents the API handler to generate and return an ID request token. | ||
| func GetIDRequestToken(c *gin.Context) { | ||
| // capture middleware values | ||
| b := build.Retrieve(c) | ||
| cl := claims.Retrieve(c) | ||
|
|
||
| // update engine logger with API metadata | ||
| // | ||
| // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields | ||
| logrus.WithFields(logrus.Fields{ | ||
| "build": b.GetNumber(), | ||
| "org": b.GetRepo().GetOrg(), | ||
| "repo": b.GetRepo().GetName(), | ||
| "user": cl.Subject, | ||
| }).Infof("generating ID request token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) | ||
|
|
||
| image := c.Query("image") | ||
| if len(image) == 0 { | ||
| retErr := errors.New("no step 'image' provided in query parameters") | ||
|
|
||
| util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| request := c.Query("request") | ||
| if len(request) == 0 { | ||
| retErr := errors.New("no 'request' provided in query parameters") | ||
|
|
||
| util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| commands, err := strconv.ParseBool(c.Query("commands")) | ||
| if err != nil { | ||
| retErr := fmt.Errorf("unable to parse 'commands' query parameter as boolean %s: %w", c.Query("commands"), err) | ||
|
|
||
| util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| // retrieve token manager from context | ||
| tm := c.MustGet("token-manager").(*token.Manager) | ||
|
|
||
| exp := (time.Duration(b.GetRepo().GetTimeout()) * time.Minute) + tm.BuildTokenBufferDuration | ||
|
|
||
| // set mint token options | ||
| idmto := &token.MintTokenOpts{ | ||
| Build: b, | ||
| Repo: b.GetRepo().GetFullName(), | ||
| TokenType: constants.IDRequestTokenType, | ||
| TokenDuration: exp, | ||
| Image: util.Sanitize(image), | ||
| Request: util.Sanitize(request), | ||
| Commands: commands, | ||
| } | ||
|
|
||
| // mint token | ||
| idrt, err := tm.MintToken(idmto) | ||
| if err != nil { | ||
| retErr := fmt.Errorf("unable to generate ID request token: %w", err) | ||
|
|
||
| util.HandleError(c, http.StatusInternalServerError, retErr) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| c.JSON(http.StatusOK, library.Token{Token: &idrt}) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package build | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "net/http" | ||
|
|
||
| "github.com/gin-gonic/gin" | ||
| "github.com/sirupsen/logrus" | ||
|
|
||
| "github.com/go-vela/server/constants" | ||
| "github.com/go-vela/server/database" | ||
| "github.com/go-vela/server/internal/token" | ||
| "github.com/go-vela/server/router/middleware/build" | ||
| "github.com/go-vela/server/router/middleware/claims" | ||
| "github.com/go-vela/server/util" | ||
| "github.com/go-vela/types/library" | ||
| ) | ||
|
|
||
| // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_token builds GetIDToken | ||
| // | ||
| // Get a Vela OIDC token associated with a build | ||
| // | ||
| // --- | ||
| // produces: | ||
| // - application/json | ||
| // parameters: | ||
| // - in: path | ||
| // name: repo | ||
| // description: Name of the repo | ||
| // required: true | ||
| // type: string | ||
| // - in: path | ||
| // name: org | ||
| // description: Name of the org | ||
| // required: true | ||
| // type: string | ||
| // - in: path | ||
| // name: build | ||
| // description: Build number | ||
| // required: true | ||
| // type: integer | ||
| // - in: query | ||
| // name: audience | ||
| // description: Add audience to token claims | ||
| // type: array | ||
| // items: | ||
| // type: string | ||
| // collectionFormat: multi | ||
| // security: | ||
| // - ApiKeyAuth: [] | ||
| // responses: | ||
| // '200': | ||
| // description: Successfully retrieved ID token | ||
| // schema: | ||
| // "$ref": "#/definitions/Token" | ||
| // '400': | ||
| // description: Bad request | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
| // '401': | ||
| // description: Unauthorized request | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
| // '404': | ||
| // description: Unable to find build | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
| // '500': | ||
| // description: Unable to generate id token | ||
| // schema: | ||
| // "$ref": "#/definitions/Error" | ||
|
|
||
| // GetIDToken represents the API handler to generate a id token. | ||
| func GetIDToken(c *gin.Context) { | ||
| // capture middleware values | ||
| b := build.Retrieve(c) | ||
| cl := claims.Retrieve(c) | ||
| ctx := c.Request.Context() | ||
|
|
||
| // update engine logger with API metadata | ||
| // | ||
| // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields | ||
| logrus.WithFields(logrus.Fields{ | ||
| "build": b.GetNumber(), | ||
| "org": b.GetRepo().GetOrg(), | ||
| "repo": b.GetRepo().GetName(), | ||
| "subject": cl.Subject, | ||
| }).Infof("generating ID token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) | ||
|
|
||
| // retrieve token manager from context | ||
| tm := c.MustGet("token-manager").(*token.Manager) | ||
|
|
||
| // set mint token options | ||
| idmto := &token.MintTokenOpts{ | ||
| Build: b, | ||
| Repo: b.GetRepo().GetFullName(), | ||
| TokenType: constants.IDTokenType, | ||
| TokenDuration: tm.IDTokenDuration, | ||
| Image: cl.Image, | ||
| Request: cl.Request, | ||
| Commands: cl.Commands, | ||
| } | ||
|
|
||
| // if audience is provided, include that in claims | ||
| audience := []string{} | ||
|
|
||
| if len(c.QueryArray("audience")) > 0 { | ||
ecrupper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| for _, a := range c.QueryArray("audience") { | ||
plyr4 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if len(a) > 0 { | ||
| audience = append(audience, util.Sanitize(a)) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if len(audience) == 0 { | ||
| retErr := fmt.Errorf("unable to generate ID token: %s", "no audience provided") | ||
|
|
||
| util.HandleError(c, http.StatusBadRequest, retErr) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| idmto.Audience = audience | ||
|
|
||
| // mint token | ||
| idt, err := tm.MintIDToken(ctx, idmto, database.FromContext(c)) | ||
| if err != nil { | ||
| retErr := fmt.Errorf("unable to generate ID token: %w", err) | ||
|
|
||
| util.HandleError(c, http.StatusInternalServerError, retErr) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| c.JSON(http.StatusOK, library.Token{Token: &idt}) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.