Skip to content

Commit a5f9e29

Browse files
authored
feat: implement trigger and project/group deploy tokens (#140)
1 parent 9fd14ef commit a5f9e29

File tree

165 files changed

+9237
-2814
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

165 files changed

+9237
-2814
lines changed

.github/workflows/go.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- name: Build
2323
run: go build ./cmd/vault-plugin-secrets-gitlab
2424
- name: Test
25-
run: go test -cover -coverprofile=coverage.out
25+
run: go test -cover -coverprofile=coverage.out -tags unit,selfhosted,saas,local
2626
env:
2727
GITLAB_SERVICE_ACCOUNT_URL: ${{ vars.GITLAB_SERVICE_ACCOUNT_URL }}
2828
- name: Upload coverage reports to Codecov

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ fabric.properties
3838
go.work
3939
tmp/
4040
bin/
41+
/coverage.html
42+
/coverage.out
43+
.envrc

.idea/vault-plugin-secrets-gitlab.iml

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+49-7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ through Vault.
1717
- Gitlab Group Access Tokens - https://docs.gitlab.com/ee/api/group_access_tokens.html
1818
- Gitlab User Service Account Tokens - https://docs.gitlab.com/ee/api/users.html#create-service-account-user
1919
- Gitlab Group Service Account Tokens - https://docs.gitlab.com/ee/api/group_service_accounts.html
20+
- Gitlab Pipeline Project Trigger Tokens - https://docs.gitlab.com/ee/api/pipeline_triggers.html
21+
- Gitlab Group/Project Deploy Tokens - https://docs.gitlab.com/ee/user/project/deploy_tokens
2022

2123
## Getting Started
2224

@@ -92,7 +94,7 @@ The current authentication model requires providing Vault with a Gitlab Token.
9294
| base_url | yes | n/a | no | The address to access Gitlab |
9395
| auto_rotate_token | no | no | no | Should we autorotate the token when it's close to expiry? (Experimental) |
9496
| 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 |
95-
| type | yes | n/a | no | The type of gitlab instance that we use can be one of saas, self-managed or dedicated |
97+
| type | yes | n/a | no | The type of gitlab instance that we use can be one of saas, self-managed or dedicated |
9698
9799
### Role
98100
@@ -105,11 +107,41 @@ The current authentication model requires providing Vault with a Gitlab Token.
105107
| scopes | no | [] | no | List of scopes |
106108
| token_type | yes | n/a | no | Access token type |
107109
| gitlab_revokes_token | no | no | no | Gitlab revokes the token when it's time. Vault will not revoke the token when the lease expires |
108-
| config_name | no | default | no | The configuration to use for the role |
110+
| config_name | no | default | no | The configuration to use for the role |
109111
110112
#### path
111113
112-
If `token_type` is `group-service-account` then the format of the path is `{groupId}/{serviceAccountName}` example `265/service_account_65c74d39b4f71fc3fdc72330fce28c28`.
114+
##### `token_type` is `personal`
115+
116+
Format of the path is `{username}` example `admin`.
117+
118+
##### `token_type` is `project`
119+
120+
Format of the path is the full path of the project for example `group/project` or `group/subgroup/project`
121+
122+
##### `token_type` is `group`
123+
124+
Format of the path is the full path of the project for example `group` or `group/subgroup`
125+
126+
##### `token_type` is `user-service-account`
127+
128+
Format of the path is `{username}` example `service_account_65c74d39b4f71fc3fdc72330fce28c28`.
129+
130+
##### `token_type` is `group-service-account`
131+
132+
Format of the path is `{groupId}/{serviceAccountName}` example `265/service_account_65c74d39b4f71fc3fdc72330fce28c28`.
133+
134+
##### `token_type` is `project-deploy`
135+
136+
Format of the path is the full path of the project for example `group/project` or `group/subgroup/project`
137+
138+
##### `token_type` is `group-deploy`
139+
140+
Format of the path is the full path of the project for example `group` or `group/subgroup`
141+
142+
##### `token_type` is `pipeline-project-trigger`
143+
144+
Format of the path is the full path of the project for example `group/project` or `group/subgroup/project`
113145
114146
#### name
115147
@@ -154,17 +186,20 @@ Depending on `gitlab_revokes_token` the TTL will change.
154186
155187
#### access_level
156188
157-
It's not required if `token_type` is set to `personal`.
189+
It's not required if `token_type` is set to `personal`, `pipeline-project-trigger`, `project-deploy`, `group-deploy`.
158190
159191
For a list of available roles check https://docs.gitlab.com/ee/user/permissions.html
160192
161193
#### scopes
162194
195+
It's not required if `token_type` is set to `pipeline-project-trigger`.
196+
163197
Depending on the type of token you have different scopes:
164198
165199
* `Personal` - https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#personal-access-token-scopes
166200
* `Project` - https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#scopes-for-a-project-access-token
167201
* `Group` - https://docs.gitlab.com/ee/user/group/settings/group_access_tokens.html#scopes-for-a-group-access-token
202+
* `Deploy` - https://docs.gitlab.com/ee/user/project/deploy_tokens/#scope
168203
169204
#### token_types
170205
@@ -175,6 +210,9 @@ Can be
175210
* group
176211
* user-service-account
177212
* group-service-account
213+
* pipeline-project-trigger
214+
* project-deploy
215+
* group-deploy
178216
179217
#### gitlab_revokes_token
180218
@@ -223,6 +261,9 @@ token_expires_at 2025-07-11T00:00:00Z
223261
token_id 1
224262
token_sha1_hash 9441e6e07d77a2d5601ab5d7cac5868d358d885c
225263
type self-managed
264+
gitlab_version 17.5.3-ee
265+
gitlab_revision 9d81c27eee7
266+
gitlab_is_enterprise true
226267
```
227268
228269
After initial setup should you wish to change any value you can do so by using the patch command for example
@@ -241,6 +282,9 @@ token_expires_at 2025-07-11T00:00:00Z
241282
token_id 2
242283
token_sha1_hash c6e762667cadb936f0c8439b0d240661a270eba1
243284
type saas
285+
gitlab_version 17.7.0-pre
286+
gitlab_revision 22e9474dc6b
287+
gitlab_is_enterprise true
244288
```
245289
246290
All the config properties as defined above in the Config section can be patched.
@@ -257,8 +301,6 @@ $ vault secrets tune -max-lease-ttl=8784h -default-lease-ttl=168h gitlab/
257301
Check https://developer.hashicorp.com/vault/docs/commands/secrets/tune for more information.
258302
259303
There is a periodic func that runs that is responsible for autorotation and main token expiry time.
260-
So in the beginning you may see `token_expires_at n/a`. But when the function runs it will update itself
261-
with the correct expiry date and the corresponding `token_id`.
262304
263305
### Roles
264306
@@ -326,7 +368,7 @@ token_sha1_hash 91a91bb30f816770081c570504c5e2723bcb1f38
326368
type self-managed
327369
```
328370
329-
**Important**: Token will be showed after rotation, it will not be shown again.
371+
**Important**: Token will be shown only after rotation, and it will not be shown again.
330372
331373
## Upgrading
332374

backend.go

+2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ func (b *Backend) periodicFunc(ctx context.Context, req *logical.Request) (err e
9595
unlockLockClientMutex := sync.OnceFunc(func() { b.lockClientMutex.Unlock() })
9696
defer unlockLockClientMutex()
9797

98+
// @TODO: Check and fix this is not correct, the locking mechanism doesn't make sense
99+
98100
var configs []string
99101
configs, err = req.Storage.List(ctx, fmt.Sprintf("%s/", PathConfigStorage))
100102

backend_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build unit
2+
13
package gitlab_test
24

35
import (
@@ -12,7 +14,7 @@ import (
1214
func TestBackend(t *testing.T) {
1315
var err error
1416
var b *gitlab.Backend
15-
ctx := getCtxGitlabClient(t)
17+
ctx := getCtxGitlabClient(t, "unit")
1618
b, _, err = getBackend(ctx)
1719
require.NoError(t, err)
1820
require.NotNil(t, b)

cmd/vault-plugin-secrets-gitlab/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/hashicorp/go-hclog"
77
"github.com/hashicorp/vault/api"
88
"github.com/hashicorp/vault/sdk/plugin"
9+
910
gat "github.com/ilijamt/vault-plugin-secrets-gitlab"
1011
)
1112

defs_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build !integration
1+
//go:build unit
22

33
package gitlab_test
44

entry_config.go

+26-20
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@ import (
1414
)
1515

1616
type EntryConfig struct {
17-
TokenId int `json:"token_id" yaml:"token_id" mapstructure:"token_id"`
18-
BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"`
19-
Token string `json:"token" structs:"token" mapstructure:"token"`
20-
AutoRotateToken bool `json:"auto_rotate_token" structs:"auto_rotate_token" mapstructure:"auto_rotate_token"`
21-
AutoRotateBefore time.Duration `json:"auto_rotate_before" structs:"auto_rotate_before" mapstructure:"auto_rotate_before"`
22-
TokenCreatedAt time.Time `json:"token_created_at" structs:"token_created_at" mapstructure:"token_created_at"`
23-
TokenExpiresAt time.Time `json:"token_expires_at" structs:"token_expires_at" mapstructure:"token_expires_at"`
24-
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
25-
Type Type `json:"type" structs:"type" mapstructure:"type"`
26-
Name string `json:"name" structs:"name" mapstructure:"name"`
17+
TokenId int `json:"token_id" yaml:"token_id" mapstructure:"token_id"`
18+
BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"`
19+
Token string `json:"token" structs:"token" mapstructure:"token"`
20+
AutoRotateToken bool `json:"auto_rotate_token" structs:"auto_rotate_token" mapstructure:"auto_rotate_token"`
21+
AutoRotateBefore time.Duration `json:"auto_rotate_before" structs:"auto_rotate_before" mapstructure:"auto_rotate_before"`
22+
TokenCreatedAt time.Time `json:"token_created_at" structs:"token_created_at" mapstructure:"token_created_at"`
23+
TokenExpiresAt time.Time `json:"token_expires_at" structs:"token_expires_at" mapstructure:"token_expires_at"`
24+
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
25+
Type Type `json:"type" structs:"type" mapstructure:"type"`
26+
Name string `json:"name" structs:"name" mapstructure:"name"`
27+
GitlabVersion string `json:"gitlab_version" structs:"gitlab_version" mapstructure:"gitlab_version"`
28+
GitlabRevision string `json:"gitlab_revision" structs:"gitlab_revision" mapstructure:"gitlab_revision"`
29+
GitlabIsEnterprise bool `json:"gitlab_is_enterprise" structs:"gitlab_is_enterprise" mapstructure:"gitlab_is_enterprise"`
2730
}
2831

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

148151
return map[string]any{
149-
"base_url": e.BaseURL,
150-
"auto_rotate_token": e.AutoRotateToken,
151-
"auto_rotate_before": e.AutoRotateBefore.String(),
152-
"token_id": e.TokenId,
153-
"token_created_at": tokenCreatedAt,
154-
"token_expires_at": tokenExpiresAt,
155-
"token_sha1_hash": fmt.Sprintf("%x", sha1.Sum([]byte(e.Token))),
156-
"scopes": strings.Join(e.Scopes, ", "),
157-
"type": e.Type.String(),
158-
"name": e.Name,
152+
"base_url": e.BaseURL,
153+
"auto_rotate_token": e.AutoRotateToken,
154+
"auto_rotate_before": e.AutoRotateBefore.String(),
155+
"token_id": e.TokenId,
156+
"gitlab_version": e.GitlabVersion,
157+
"gitlab_revision": e.GitlabRevision,
158+
"gitlab_is_enterprise": e.GitlabIsEnterprise,
159+
"token_created_at": tokenCreatedAt,
160+
"token_expires_at": tokenExpiresAt,
161+
"token_sha1_hash": fmt.Sprintf("%x", sha1.Sum([]byte(e.Token))),
162+
"scopes": strings.Join(e.Scopes, ", "),
163+
"type": e.Type.String(),
164+
"name": e.Name,
159165
}
160166
}
161167

entry_config_merge_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build unit
2+
13
package gitlab_test
24

35
import (

entry_config_update_form_field_data_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build unit
2+
13
package gitlab_test
24

35
import (

0 commit comments

Comments
 (0)