Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
ilijamt committed Aug 30, 2023
0 parents commit 8bc2e1f
Show file tree
Hide file tree
Showing 36 changed files with 3,442 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
43 changes: 43 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: "CodeQL Analysis"

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '43 9 * * 5'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'go' ]

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}


- name: Autobuild
uses: github/codeql-action/autobuild@v2


- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
36 changes: 36 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: golangci-lint

on:
push:
branches:
- main
paths:
- "**.go"
pull_request:
branches:
- main
paths:
- "**.go"

permissions:
contents: read

jobs:
golangci:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go: [1.19 1.20 1.21 1.22]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- name: Setup Go ${{ matrix.go }}
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
- name: Display Go version
run: go version
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
40 changes: 40 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
.idea/**/aws.xml
.idea/**/contentModel.xml
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
.idea/**/gradle.xml
.idea/**/libraries
cmake-build-*/
.idea/**/mongoSettings.xml
*.iws
out/
.idea_modules/
atlassian-ide-plugin.xml
.idea/replstate.xml
.idea/sonarlint/
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
.idea/httpRequests
.idea/caches/build_file_checksums.ser
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
go.work
tmp/
bin/
8 changes: 8 additions & 0 deletions .idea/modules.xml

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

9 changes: 9 additions & 0 deletions .idea/vault-plugin-secrets-gitlab.iml

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

6 changes: 6 additions & 0 deletions .idea/vcs.xml

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

33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Vault Plugin for Gitlab Access Token
------------------------------------

This is a standalone backend plugin for use with Hashicorp Vault. This plugin allows for Gitlab to generate access tokens both personal and group.

## Quick Links

- Vault Website: [https://www.vaultproject.io]
- Gitlab Private Access Tokens: [https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html]
- Gitlab Group Access Tokens: [https://docs.gitlab.com/ee/api/group_access_tokens.html]

## Getting Started

This is a [Vault plugin](https://www.vaultproject.io/docs/plugins/plugin-architecture#plugin-catalogs)
and is meant to work with Vault. This guide assumes you have already installed Vault
and have a basic understanding of how Vault works.

Otherwise, first read this guide on how to [get started with Vault](https://www.vaultproject.io/intro/getting-started/install.html).

To learn specifically about how plugins work, see documentation on [Vault plugins](https://www.vaultproject.io/docs/plugins/plugin-architecture#plugin-catalog).

### Setup

Before we can use this plugin we need to create an access token that will have rights to do what we need to.

## Security Model

The current authentication model requires providing Vault with a Gitlab Token.

## TODO

[ ] Implement autorotation of the main token
[ ] Add tests against real Gitlab instance
113 changes: 113 additions & 0 deletions backend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package gitlab

import (
"context"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/locksutil"
"github.com/hashicorp/vault/sdk/logical"
"strings"
"sync"
)

const (
// operationPrefixGitlabAccessTokens is used as expected prefix for OpenAPI operation id's.
operationPrefixGitlabAccessTokens = "gitlab"

backendHelp = `
The Gitlab Access token auth Backend dynamically generates private
and group tokens.
After mounting this Backend, credentials to manage Gitlab tokens must be configured
with the "config/" endpoints.
`
)

// Factory returns expected new Backend as logical.Backend
func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) {
var b = &Backend{
roleLocks: locksutil.CreateLocks(),
}

b.Backend = &framework.Backend{
BackendType: logical.TypeLogical,
Help: strings.TrimSpace(backendHelp),
Invalidate: b.Invalidate,

PathsSpecial: &logical.Paths{
LocalStorage: []string{
framework.WALPrefix,
},
SealWrapStorage: []string{
PathConfigStorage,
},
},

Secrets: []*framework.Secret{
secretAccessTokens(b),
},

Paths: framework.PathAppend(
[]*framework.Path{
pathConfig(b),
pathListRoles(b),
pathRoles(b),
pathTokenRoles(b),
},
),
}

b.SetClient(nil)
if err := b.Setup(ctx, conf); err != nil {
return nil, err
}

return b, nil
}

type Backend struct {
*framework.Backend

// The client that we can use to create and revoke the access tokens
client Client

// Mutex to protect access to gitlab clients and client configs, a change to the gitlab client config
// would invalidate the gitlab client, so it will need to be reinitialized
lockClientMutex sync.RWMutex

// roleLocks to protect access for roles, during modifications, deletion
roleLocks []*locksutil.LockEntry
}

// Invalidate invalidates the key if required
func (b *Backend) Invalidate(ctx context.Context, key string) {
b.Logger().Debug("Backend invalidate", "key", key)
if key == PathConfigStorage {
b.Logger().Warn("gitlab config changed, reinitializing the gitlab client")
b.lockClientMutex.Lock()
defer b.lockClientMutex.Unlock()
b.client = nil
}
}

func (b *Backend) SetClient(client Client) {
b.client = client
}

func (b *Backend) getClient(ctx context.Context, s logical.Storage) (Client, error) {
if b.client != nil && b.client.Valid() {
return b.client, nil
}

b.lockClientMutex.RLock()
defer b.lockClientMutex.RUnlock()
config, err := getConfig(ctx, s)
if err != nil {
return nil, err
}

client, err := NewGitlabClient(config)
if err == nil {
b.SetClient(client)
}
return client, err
}
Loading

0 comments on commit 8bc2e1f

Please sign in to comment.