Skip to content
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

feat: implement trigger and project/group deploy tokens #140

Merged
merged 16 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Build
run: go build ./cmd/vault-plugin-secrets-gitlab
- name: Test
run: go test -cover -coverprofile=coverage.out
run: go test -cover -coverprofile=coverage.out -tags unit,selfhosted,saas,local
env:
GITLAB_SERVICE_ACCOUNT_URL: ${{ vars.GITLAB_SERVICE_ACCOUNT_URL }}
- name: Upload coverage reports to Codecov
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ fabric.properties
go.work
tmp/
bin/
/coverage.html
/coverage.out
.envrc
5 changes: 4 additions & 1 deletion .idea/vault-plugin-secrets-gitlab.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 49 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ through Vault.
- Gitlab Group Access Tokens - https://docs.gitlab.com/ee/api/group_access_tokens.html
- Gitlab User Service Account Tokens - https://docs.gitlab.com/ee/api/users.html#create-service-account-user
- Gitlab Group Service Account Tokens - https://docs.gitlab.com/ee/api/group_service_accounts.html
- Gitlab Pipeline Project Trigger Tokens - https://docs.gitlab.com/ee/api/pipeline_triggers.html
- Gitlab Group/Project Deploy Tokens - https://docs.gitlab.com/ee/user/project/deploy_tokens

## Getting Started

Expand Down Expand Up @@ -92,7 +94,7 @@ The current authentication model requires providing Vault with a Gitlab Token.
| base_url | yes | n/a | no | The address to access Gitlab |
| auto_rotate_token | no | no | no | Should we autorotate the token when it's close to expiry? (Experimental) |
| auto_rotate_before | no | 24h | no | How much time should be remaining on the token validity before we should rotate it? Minimum can be set to 24h and maximum to 730h |
| type | yes | n/a | no | The type of gitlab instance that we use can be one of saas, self-managed or dedicated |
| type | yes | n/a | no | The type of gitlab instance that we use can be one of saas, self-managed or dedicated |

### Role

Expand All @@ -105,11 +107,41 @@ The current authentication model requires providing Vault with a Gitlab Token.
| scopes | no | [] | no | List of scopes |
| token_type | yes | n/a | no | Access token type |
| gitlab_revokes_token | no | no | no | Gitlab revokes the token when it's time. Vault will not revoke the token when the lease expires |
| config_name | no | default | no | The configuration to use for the role |
| config_name | no | default | no | The configuration to use for the role |

#### path

If `token_type` is `group-service-account` then the format of the path is `{groupId}/{serviceAccountName}` example `265/service_account_65c74d39b4f71fc3fdc72330fce28c28`.
##### `token_type` is `personal`

Format of the path is `{username}` example `admin`.

##### `token_type` is `project`

Format of the path is the full path of the project for example `group/project` or `group/subgroup/project`

##### `token_type` is `group`

Format of the path is the full path of the project for example `group` or `group/subgroup`

##### `token_type` is `user-service-account`

Format of the path is `{username}` example `service_account_65c74d39b4f71fc3fdc72330fce28c28`.

##### `token_type` is `group-service-account`

Format of the path is `{groupId}/{serviceAccountName}` example `265/service_account_65c74d39b4f71fc3fdc72330fce28c28`.

##### `token_type` is `project-deploy`

Format of the path is the full path of the project for example `group/project` or `group/subgroup/project`

##### `token_type` is `group-deploy`

Format of the path is the full path of the project for example `group` or `group/subgroup`

##### `token_type` is `pipeline-project-trigger`

Format of the path is the full path of the project for example `group/project` or `group/subgroup/project`

#### name

Expand Down Expand Up @@ -154,17 +186,20 @@ Depending on `gitlab_revokes_token` the TTL will change.

#### access_level

It's not required if `token_type` is set to `personal`.
It's not required if `token_type` is set to `personal`, `pipeline-project-trigger`, `project-deploy`, `group-deploy`.

For a list of available roles check https://docs.gitlab.com/ee/user/permissions.html

#### scopes

It's not required if `token_type` is set to `pipeline-project-trigger`.

Depending on the type of token you have different scopes:

* `Personal` - https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#personal-access-token-scopes
* `Project` - https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#scopes-for-a-project-access-token
* `Group` - https://docs.gitlab.com/ee/user/group/settings/group_access_tokens.html#scopes-for-a-group-access-token
* `Deploy` - https://docs.gitlab.com/ee/user/project/deploy_tokens/#scope

#### token_types

Expand All @@ -175,6 +210,9 @@ Can be
* group
* user-service-account
* group-service-account
* pipeline-project-trigger
* project-deploy
* group-deploy

#### gitlab_revokes_token

Expand Down Expand Up @@ -223,6 +261,9 @@ token_expires_at 2025-07-11T00:00:00Z
token_id 1
token_sha1_hash 9441e6e07d77a2d5601ab5d7cac5868d358d885c
type self-managed
gitlab_version 17.5.3-ee
gitlab_revision 9d81c27eee7
gitlab_is_enterprise true
```

After initial setup should you wish to change any value you can do so by using the patch command for example
Expand All @@ -241,6 +282,9 @@ token_expires_at 2025-07-11T00:00:00Z
token_id 2
token_sha1_hash c6e762667cadb936f0c8439b0d240661a270eba1
type saas
gitlab_version 17.7.0-pre
gitlab_revision 22e9474dc6b
gitlab_is_enterprise true
```

All the config properties as defined above in the Config section can be patched.
Expand All @@ -257,8 +301,6 @@ $ vault secrets tune -max-lease-ttl=8784h -default-lease-ttl=168h gitlab/
Check https://developer.hashicorp.com/vault/docs/commands/secrets/tune for more information.

There is a periodic func that runs that is responsible for autorotation and main token expiry time.
So in the beginning you may see `token_expires_at n/a`. But when the function runs it will update itself
with the correct expiry date and the corresponding `token_id`.

### Roles

Expand Down Expand Up @@ -326,7 +368,7 @@ token_sha1_hash 91a91bb30f816770081c570504c5e2723bcb1f38
type self-managed
```

**Important**: Token will be showed after rotation, it will not be shown again.
**Important**: Token will be shown only after rotation, and it will not be shown again.

## Upgrading

Expand Down
2 changes: 2 additions & 0 deletions backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ func (b *Backend) periodicFunc(ctx context.Context, req *logical.Request) (err e
unlockLockClientMutex := sync.OnceFunc(func() { b.lockClientMutex.Unlock() })
defer unlockLockClientMutex()

// @TODO: Check and fix this is not correct, the locking mechanism doesn't make sense

var configs []string
configs, err = req.Storage.List(ctx, fmt.Sprintf("%s/", PathConfigStorage))

Expand Down
4 changes: 3 additions & 1 deletion backend_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build unit

package gitlab_test

import (
Expand All @@ -12,7 +14,7 @@ import (
func TestBackend(t *testing.T) {
var err error
var b *gitlab.Backend
ctx := getCtxGitlabClient(t)
ctx := getCtxGitlabClient(t, "unit")
b, _, err = getBackend(ctx)
require.NoError(t, err)
require.NotNil(t, b)
Expand Down
1 change: 1 addition & 0 deletions cmd/vault-plugin-secrets-gitlab/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/plugin"

gat "github.com/ilijamt/vault-plugin-secrets-gitlab"
)

Expand Down
2 changes: 1 addition & 1 deletion defs_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !integration
//go:build unit

package gitlab_test

Expand Down
46 changes: 26 additions & 20 deletions entry_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ import (
)

type EntryConfig struct {
TokenId int `json:"token_id" yaml:"token_id" mapstructure:"token_id"`
BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"`
Token string `json:"token" structs:"token" mapstructure:"token"`
AutoRotateToken bool `json:"auto_rotate_token" structs:"auto_rotate_token" mapstructure:"auto_rotate_token"`
AutoRotateBefore time.Duration `json:"auto_rotate_before" structs:"auto_rotate_before" mapstructure:"auto_rotate_before"`
TokenCreatedAt time.Time `json:"token_created_at" structs:"token_created_at" mapstructure:"token_created_at"`
TokenExpiresAt time.Time `json:"token_expires_at" structs:"token_expires_at" mapstructure:"token_expires_at"`
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
Type Type `json:"type" structs:"type" mapstructure:"type"`
Name string `json:"name" structs:"name" mapstructure:"name"`
TokenId int `json:"token_id" yaml:"token_id" mapstructure:"token_id"`
BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"`
Token string `json:"token" structs:"token" mapstructure:"token"`
AutoRotateToken bool `json:"auto_rotate_token" structs:"auto_rotate_token" mapstructure:"auto_rotate_token"`
AutoRotateBefore time.Duration `json:"auto_rotate_before" structs:"auto_rotate_before" mapstructure:"auto_rotate_before"`
TokenCreatedAt time.Time `json:"token_created_at" structs:"token_created_at" mapstructure:"token_created_at"`
TokenExpiresAt time.Time `json:"token_expires_at" structs:"token_expires_at" mapstructure:"token_expires_at"`
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
Type Type `json:"type" structs:"type" mapstructure:"type"`
Name string `json:"name" structs:"name" mapstructure:"name"`
GitlabVersion string `json:"gitlab_version" structs:"gitlab_version" mapstructure:"gitlab_version"`
GitlabRevision string `json:"gitlab_revision" structs:"gitlab_revision" mapstructure:"gitlab_revision"`
GitlabIsEnterprise bool `json:"gitlab_is_enterprise" structs:"gitlab_is_enterprise" mapstructure:"gitlab_is_enterprise"`
}

func (e *EntryConfig) Merge(data *framework.FieldData) (warnings []string, changes map[string]string, err error) {
Expand Down Expand Up @@ -146,16 +149,19 @@ func (e *EntryConfig) LogicalResponseData() map[string]any {
}

return map[string]any{
"base_url": e.BaseURL,
"auto_rotate_token": e.AutoRotateToken,
"auto_rotate_before": e.AutoRotateBefore.String(),
"token_id": e.TokenId,
"token_created_at": tokenCreatedAt,
"token_expires_at": tokenExpiresAt,
"token_sha1_hash": fmt.Sprintf("%x", sha1.Sum([]byte(e.Token))),
"scopes": strings.Join(e.Scopes, ", "),
"type": e.Type.String(),
"name": e.Name,
"base_url": e.BaseURL,
"auto_rotate_token": e.AutoRotateToken,
"auto_rotate_before": e.AutoRotateBefore.String(),
"token_id": e.TokenId,
"gitlab_version": e.GitlabVersion,
"gitlab_revision": e.GitlabRevision,
"gitlab_is_enterprise": e.GitlabIsEnterprise,
"token_created_at": tokenCreatedAt,
"token_expires_at": tokenExpiresAt,
"token_sha1_hash": fmt.Sprintf("%x", sha1.Sum([]byte(e.Token))),
"scopes": strings.Join(e.Scopes, ", "),
"type": e.Type.String(),
"name": e.Name,
}
}

Expand Down
2 changes: 2 additions & 0 deletions entry_config_merge_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build unit

package gitlab_test

import (
Expand Down
2 changes: 2 additions & 0 deletions entry_config_update_form_field_data_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build unit

package gitlab_test

import (
Expand Down
Loading
Loading