gitlab

package module
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2024 License: MIT Imports: 25 Imported by: 0

README

Vault Plugin for Gitlab Access Token

Go Report Card Codecov GitHub go.mod Go version (subdirectory of monorepo) GitHub

This is a standalone backend plugin for use with Hashicorp Vault. This plugin allows for Gitlab to generate personal, project and group access tokens. This was created so we can automate the creation/revocation of access tokens through Vault.

Getting Started

This is a Vault plugin 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.

To learn specifically about how plugins work, see documentation on Vault plugins.

GitLab

  • GitLab CE/EE - Self Managed
  • gitlab.com (cannot use personal access token, and user service account)
  • Dedicated Instance (cannot use personal access token, and user service account)

Setup

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

Paths

For a list of the available endpoints you can check bellow or by running the command vault path-help gitlab for your version after you've mounted it.

$ vault path-help gitlab
## DESCRIPTION

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/(?P<config_name>\w(([\w-.@]+)?\w)?)$" endpoints.

## PATHS

The following paths are supported by this backend. To view help for
any of the paths below, use the help command with any route matching
the path pattern. Note that depending on the policy of your auth token,
you may or may not be able to access certain paths.

    ^config/(?P<config_name>\w(([\w-.]+)?\w)?)$
        Configure the Gitlab Access Tokens Backend.

    ^config/(?P<config_name>\w(([\w-.]+)?\w)?)/rotate$
        Rotate the gitlab token for this configuration.

    ^config?/?$
        Lists existing configs

    ^roles/(?P<role_name>\w(([\w-.]+)?\w)?)$
        Create a role with parameters that are used to generate a various access tokens.

    ^roles?/?$
        Lists existing roles

    ^token/(?P<role_name>\w(([\w-.]+)?\w)?)$
        Generate an access token based on the specified role

Security Model

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

Configuration

Config

Property Required Default value Sensitive Description
token yes n/a yes The token to access Gitlab API, it will not show when you do a read, as it's a sensitive value. Instead it will display it's SHA1 hash value.
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-hosted or dedicated

Role

Property Required Default value Sensitive Description
path yes n/a no Project/Group path to create an access token for. If the token type is set to personal then write the username here.
name yes n/a no The name of the access token
ttl yes n/a no The TTL of the token
access_level no/yes n/a no Access level of access token (only required for Group and Project access tokens)
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
path

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

name

When generating a token, you have control over the token's name by using templating. The name is constructed using Go's text/template, which allows for dynamic generation of names based on available data. You can refer to Go's text/template documentation for examples and guidance on how to use it effectively.

Important: GitLab does not permit duplicate token names. If your template doesn't ensure unique names, token generation will fail.

Here are some examples of effective token name templates:

  • vault-generated-{{ .token_type }}-access-token-{{ randHexString 4 }}
  • {{ .role_name }}-{{ .token_type }}-{{ randHexString 4 }}
Data

The following data points can be used within your token name template. These are derived from the role for which the token is being generated:

  • path
  • ttl
  • access_level
  • scopes
  • token_type
  • role_name
  • config_name
  • gitlab_revokes_token
  • unix_timestamp_utc
Functions

You can also use the following functions within your template:

  • randHexString(bytes int) string - Generates a random hexadecimal string with the specified number of bytes.
  • stringsJoin(elems []string, sep string) string - joins a list of elems strings with a sep
  • yesNoBool(in bool) string - just return yes if in is true otherwise it returns no
  • timeNowFormat(layout string) string - layout is a go time format string layout
ttl

Depending on gitlab_revokes_token the TTL will change.

  • true - 24h <= ttl <= 365 days
  • false - 1h <= ttl <= 365 days
access_level

It's not required if token_type is set to personal.

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

scopes

Depending on the type of token you have different scopes:

token_types

Can be

  • personal
  • project
  • group
  • user-service-account
  • group-service-account
gitlab_revokes_token

This is a flag that doesn't expire the token when the token used to create the credentials expire. When the vault token used to create gitlab credentials with a TTL longer than the vault token, the new gitlab credentials will expire at the same time with the parent. Setting this up will not call the revoke endpoint on gitlab.

Examples

Setup

Before we can use the plugin we need to register and enable it in Vault.

vault plugin register \
  -sha256=$(sha256sum path/to/plugin/directory/gitlab | cut -d " " -f 1) \
  -command=vault-plugin-secrets-gitlab \
  secret gitlab

vault secrets enable gitlab

Config

Due to how Gitlab manages expiration the minimum is 24h and maximum is 365 days. As per non-expiring-access-tokens and Remove ability to create deprecated non-expiring access tokens. Since Gitlab 16.0 the ability to create non expiring token has been removed.

If you use Vault to manage the tokens the minimal TTL you can use is 1h, by setting gitlab_revokes_token=false.

The command bellow will set up the config backend with a max TTL of 48h.

$ vault write gitlab/config/default base_url=https://gitlab.example.com token=gitlab-super-secret-token auto_rotate_token=false auto_rotate_before=48h type=self-managed
$ vault read gitlab/config/default
Key                   Value
---                   -----
auto_rotate_before    48h0m0s
auto_rotate_token     false
base_url              http://localhost:8080
name                  default
scopes                api, read_api, read_user, sudo, admin_mode, create_runner, k8s_proxy, read_repository, write_repository, ai_features, read_service_ping
token_created_at      2024-07-11T18:53:26Z
token_expires_at      2025-07-11T00:00:00Z
token_id              1
token_sha1_hash       9441e6e07d77a2d5601ab5d7cac5868d358d885c
type                  self-managed

After initial setup should you wish to change any value you can do so by using the patch command for example

$ vault patch gitlab/config/default type=saas auto_rotate_token=true auto_rotate_before=64h token=glpat-secret-admin-token
Key                   Value
---                   -----
auto_rotate_before    64h0m0s
auto_rotate_token     true
base_url              http://localhost:8080
name                  default
scopes                api, read_api, read_user, sudo, admin_mode, create_runner, k8s_proxy, read_repository, write_repository, ai_features, read_service_ping
token_created_at      2024-07-11T18:53:46Z
token_expires_at      2025-07-11T00:00:00Z
token_id              2
token_sha1_hash       c6e762667cadb936f0c8439b0d240661a270eba1
type                  saas

All the config properties as defined above in the Config section can be patched.

You may also need to configure the Max/Default TTL for a token that can be issued by setting:

Max TTL: 1 year Default TTL: 1 week

$ 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

This will create multiple roles

$ vault write gitlab/roles/personal name='{{ .role_name }}-{{ .token_type }}-{{ randHexString 4 }}' path=username scopes="read_api" token_type=personal ttl=48h
$ vault write gitlab/roles/project name='{{ .role_name }}-{{ .token_type }}-{{ randHexString 4 }}' path=group/project scopes="read_api" access_level=guest token_type=project ttl=48h
$ vault write gitlab/roles/group name='{{ .role_name }}-{{ .token_type }}-{{ randHexString 4 }}' path=group/subgroup scopes="read_api" access_level=developer token_type=group ttl=48h
$ vault write gitlab/roles/sa name='{{ .role_name }}-{{ .token_type }}-{{ randHexString 4 }}' path=service_account_00b069cb73a15d0a7ba8cd67a653599c scopes="read_api" token_type=user-service-account ttl=24h
$ vault write gitlab/roles/ga name='{{ .role_name }}-{{ .token_type }}-{{ randHexString 4 }}' path=345/service_account_00b069cb73a15d0a7ba8cd67a653599c scopes="read_api" token_type=group-service-account ttl=24h
User service accounts

The service account users from Gitlab 16.1 are for all purposes users that don't use seats. So creating a service account and setting the path to the service account user would work the same as on a real user. More information can be found on https://docs.gitlab.com/ee/api/users.html#create-service-account-user.

$ curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "https://gitlab/api/v4/service_accounts" | jq .
{
  "id": 63,
  "username": "service_account_964b157dcff9bcd87dc7c0837f9c47e9",
  "name": "Service account user"
}
Group service accounts

The service account users from Gitlab 16.1 are for all purposes users that don't use seats. More information can be found on https://docs.gitlab.com/ee/api/group_service_accounts.html#create-a-service-account-user.

$ curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "https://gitlab/api/v4/groups/345/service_accounts" | jq .
{
  "id": 61,
  "username": "service_account_group_345_c468757e6df2fc104de54ea470539bb5",
  "name": "Service account user"
}

Revoke all created tokens by this plugin

$ vault lease revoke -prefix gitlab/
All revocation operations queued successfully!

Force rotation of the main token

If the original token that has been supplied to the backend is not expired. We can use the endpoint bellow to force a rotation of the main token. This would create a new token with the same expiration as the original token.

$ vault write -f gitlab/config/default/rotate
Key                   Value
---                   -----
lease_id              gitlab/config/default/rotate/Ils8dp7PDXSWgb5dF4I2NPPS
lease_duration        768h
lease_renewable       false
auto_rotate_before    64h0m0s
auto_rotate_token     true
base_url              http://localhost:8080
name                  default
scopes                api, read_api, read_user, sudo, admin_mode, create_runner, k8s_proxy, read_repository, write_repository, ai_features, read_service_ping
token_created_at      2024-07-11T18:53:46Z
token_expires_at      2024-10-12T20:02:11Z
token_id              76
token_sha1_hash       10e413692b345809f6b4db57c5d38fadaacbf9be
type                  saas

Upgrading

$ vault plugin register \
  -sha256=b5fd0a3481930211a09bb944aa96a18a9eab8e594b6773b25209330d752e5f83 \
  -command=gitlab\
  -version=v0.2.4 \
  secret \
  gitlab
$ vault secrets tune -plugin-version=v0.2.4 gitlab
$ vault plugin reload -plugin gitlab
$ vault secrets list -detailed -format=json | jq '."gitlab/"'
{
   "uuid":"759239c4-5fe1-4eb0-6105-480d1d67de5e",
   "type":"gitlab",
   "description":"",
   "accessor":"gitlab_294d3aea",
   "config":{
      "default_lease_ttl":2678400,
      "max_lease_ttl":31622400,
      "force_no_cache":false
   },
   "options":null,
   "local":false,
   "seal_wrap":false,
   "external_entropy_access":false,
   "plugin_version":"v0.2.4",
   "running_plugin_version":"v0.2.4",
   "running_sha256":"b5fd0a3481930211a09bb944aa96a18a9eab8e594b6773b25209330d752e5f83",
   "deprecation_status":""
}

Info

Running the logging with debug level will show sensitive information in the logs.

Documentation

Index

Constants

View Source
const (
	DefaultConfigFieldAccessTokenMaxTTL = 7 * 24 * time.Hour
	DefaultConfigFieldAccessTokenRotate = DefaultAutoRotateBeforeMinTTL
	DefaultRoleFieldAccessTokenMaxTTL   = 24 * time.Hour
	DefaultAccessTokenMinTTL            = 24 * time.Hour
	DefaultAccessTokenMaxPossibleTTL    = 365 * 24 * time.Hour
	DefaultAutoRotateBeforeMinTTL       = 24 * time.Hour
	DefaultAutoRotateBeforeMaxTTL       = 730 * time.Hour

	DefaultConfigName = "default"
)
View Source
const (
	PathRoleStorage   = "roles"
	TypeConfigDefault = DefaultConfigName
)
View Source
const (
	AccessLevelNoPermissions            = AccessLevel("no_permissions")
	AccessLevelMinimalAccessPermissions = AccessLevel("minimal_access")
	AccessLevelGuestPermissions         = AccessLevel("guest")
	AccessLevelReporterPermissions      = AccessLevel("reporter")
	AccessLevelDeveloperPermissions     = AccessLevel("developer")
	AccessLevelMaintainerPermissions    = AccessLevel("maintainer")
	AccessLevelOwnerPermissions         = AccessLevel("owner")

	AccessLevelUnknown = AccessLevel("")
)
View Source
const (
	// TokenScopeApi grants complete read and write access to the scoped group and related project API, including the Package Registry
	TokenScopeApi = TokenScope("api")
	// TokenScopeReadApi grants read access to the scoped group and related project API, including the Package Registry
	TokenScopeReadApi = TokenScope("read_api")
	// TokenScopeReadRegistry grants read access (pull) to the Container Registry images if any project within expected group is private and authorization is required.
	TokenScopeReadRegistry = TokenScope("read_registry")
	// TokenScopeWriteRegistry grants write access (push) to the Container Registry.
	TokenScopeWriteRegistry = TokenScope("write_registry")
	// TokenScopeReadRepository grants read access (pull) to the Container Registry images if any project within expected group is private and authorization is required
	TokenScopeReadRepository = TokenScope("read_repository")
	// TokenScopeWriteRepository grants read and write access (pull and push) to all repositories within expected group
	TokenScopeWriteRepository = TokenScope("write_repository")

	// TokenScopeCreateRunner grants permission to create runners in expected group
	TokenScopeCreateRunner = TokenScope("create_runner")
	// TokenScopeManageRunner grants permission to manage runners in expected group
	TokenScopeManageRunner = TokenScope("manage_runner")

	// TokenScopeReadUser grants read-only access to the authenticated user’s profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users.
	TokenScopeReadUser = TokenScope("read_user")
	// TokenScopeSudo grants permission to perform API actions as any user in the system, when authenticated as an administrator.
	TokenScopeSudo = TokenScope("sudo")
	// TokenScopeAdminMode grants permission to perform API actions as an administrator, when Admin Mode is enabled.
	TokenScopeAdminMode = TokenScope("admin_mode")

	// TokenScopeAiFeatures grants permission to perform API actions for GitLab Duo. This scope is designed to work with the GitLab Duo Plugin for JetBrains. For all other extensions, see scope requirements.
	TokenScopeAiFeatures = TokenScope("ai_features")
	// TokenScopeK8SProxy grants permission to perform Kubernetes API calls using the agent for Kubernetes.
	TokenScopeK8SProxy = TokenScope("k8s_proxy")
	// TokenScopeReadServicePing grant access to download Service Ping payload through the API when authenticated as an admin use.
	TokenScopeReadServicePing = TokenScope("read_service_ping")

	TokenScopeUnknown = TokenScope("")
)
View Source
const (
	TokenTypePersonal            = TokenType("personal")
	TokenTypeProject             = TokenType("project")
	TokenTypeGroup               = TokenType("group")
	TokenTypeUserServiceAccount  = TokenType("user-service-account")
	TokenTypeGroupServiceAccount = TokenType("group-service-account")

	TokenTypeUnknown = TokenType("")
)
View Source
const (
	PathConfigStorage = "config"
)
View Source
const (
	PathTokenRoleStorage = "token"
)
View Source
const (
	SecretAccessTokenType = "access_tokens"
)

Variables

View Source
var (
	ErrNilValue             = errors.New("nil value")
	ErrInvalidValue         = errors.New("invalid value")
	ErrFieldRequired        = errors.New("required field")
	ErrFieldInvalidValue    = errors.New("invalid value for field")
	ErrBackendNotConfigured = errors.New("backend not configured")
)
View Source
var (
	ErrAccessTokenNotFound = errors.New("access token not found")
	ErrRoleNotFound        = errors.New("role not found")
)
View Source
var (
	ErrUnknownAccessLevel = errors.New("unknown access level")

	ValidAccessLevels = []string{
		AccessLevelNoPermissions.String(),
		AccessLevelMinimalAccessPermissions.String(),
		AccessLevelGuestPermissions.String(),
		AccessLevelReporterPermissions.String(),
		AccessLevelDeveloperPermissions.String(),
		AccessLevelMaintainerPermissions.String(),
		AccessLevelOwnerPermissions.String(),
	}
	ValidPersonalAccessLevels = []string{
		AccessLevelUnknown.String(),
	}
	ValidUserServiceAccountAccessLevels = []string{
		AccessLevelUnknown.String(),
	}
	ValidGroupServiceAccountAccessLevels = []string{
		AccessLevelUnknown.String(),
	}
	ValidProjectAccessLevels = []string{
		AccessLevelGuestPermissions.String(),
		AccessLevelReporterPermissions.String(),
		AccessLevelDeveloperPermissions.String(),
		AccessLevelMaintainerPermissions.String(),
		AccessLevelOwnerPermissions.String(),
	}
	ValidGroupAccessLevels = []string{
		AccessLevelGuestPermissions.String(),
		AccessLevelReporterPermissions.String(),
		AccessLevelDeveloperPermissions.String(),
		AccessLevelMaintainerPermissions.String(),
		AccessLevelOwnerPermissions.String(),
	}
)
View Source
var (
	ErrUnknownTokenScope = errors.New("unknown token scope")

	ValidGroupTokenScopes   = validTokenScopes
	ValidProjectTokenScopes = validTokenScopes

	ValidPersonalTokenScopes = []string{
		TokenScopeReadServicePing.String(),
		TokenScopeReadUser.String(),
		TokenScopeSudo.String(),
		TokenScopeAdminMode.String(),
	}

	ValidUserServiceAccountTokenScopes = []string{
		TokenScopeReadServicePing.String(),
		TokenScopeReadUser.String(),
		TokenScopeSudo.String(),
		TokenScopeAdminMode.String(),
	}

	ValidGroupServiceAccountTokenScopes = []string{
		TokenScopeReadServicePing.String(),
		TokenScopeReadUser.String(),
		TokenScopeSudo.String(),
		TokenScopeAdminMode.String(),
	}
)
View Source
var BuildDate string
View Source
var (
	ErrUnknownTokenType = errors.New("unknown token type")
)
View Source
var (
	ErrUnknownType = errors.New("unknown gitlab type")
)
View Source
var (
	FieldSchemaConfig = map[string]*framework.FieldSchema{
		"token": {
			Type:        framework.TypeString,
			Description: "The API access token required for authenticating requests to the GitLab API. This token must be a valid personal access token or any other type of token supported by GitLab for API access.",
			Required:    true,
			DisplayAttrs: &framework.DisplayAttributes{
				Name:      "Token",
				Sensitive: true,
			},
		},
		"base_url": {
			Type:     framework.TypeString,
			Required: true,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "GitLab Base URL",
			},
			Description: `The base URL of your GitLab instance. This could be the URL of a self-hosted GitLab instance or the URL of the GitLab SaaS service (https://gitlab.com). The URL must be properly formatted, including the scheme (http or https). This field is essential as it determines the endpoint where API requests will be directed.`,
		},
		"type": {
			Type:     framework.TypeString,
			Required: true,
			AllowedValues: []any{
				TypeSelfManaged,
				TypeSaaS,
				TypeDedicated,
			},
			Description: `The type of GitLab instance you are connecting to. This could typically distinguish between 'self-hosted' for on-premises GitLab installations or 'saas' or 'dedicated' for the GitLab SaaS offering. This field helps the plugin to adjust any necessary configurations or request patterns specific to the type of GitLab instance.`,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "GitLab Type",
			},
		},
		"auto_rotate_token": {
			Type:        framework.TypeBool,
			Default:     false,
			Description: `Determines whether the plugin should automatically rotate the API access token as it approaches its expiration date. Enabling this feature ensures that the token is refreshed without manual intervention, reducing the risk of service disruption due to expired tokens.`,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Auto Rotate Token",
			},
		},
		"auto_rotate_before": {
			Type:        framework.TypeDurationSecond,
			Description: `Specifies the duration, in seconds, before the token's expiration at which the auto-rotation should occur. The value must be set between a minimum of 24 hours (86400 seconds) and a maximum of 730 hours (2628000 seconds). This setting allows you to control how early the token rotation should happen, balancing between proactive rotation and maximizing token lifespan.`,
			Default:     DefaultConfigFieldAccessTokenRotate,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Auto Rotate Before",
			},
		},
		"config_name": {
			Type:        framework.TypeString,
			Description: "Config name",
			Required:    true,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Config name",
			},
		},
	}
)
View Source
var (
	FieldSchemaRoles = map[string]*framework.FieldSchema{
		"role_name": {
			Type:        framework.TypeString,
			Description: "Role name",
			Required:    true,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Role Name",
			},
		},
		"path": {
			Type:        framework.TypeString,
			Description: "Project/Group path to create an access token for. If the token type is set to personal then write the username here.",
			Required:    true,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "path",
			},
		},
		"name": {
			Type:        framework.TypeString,
			Description: "The name of the access token",
			Required:    true,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Name",
			},
		},
		"scopes": {
			Type:        framework.TypeCommaStringSlice,
			Description: "List of scopes",
			Required:    false,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Scopes",
			},
			AllowedValues: allowedValues(append(validTokenScopes, ValidPersonalTokenScopes...)...),
		},
		"ttl": {
			Type:        framework.TypeDurationSecond,
			Description: "The TTL of the token",
			Required:    true,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Token TTL",
			},
		},
		"access_level": {
			Type:        framework.TypeString,
			Description: "access level of access token (only required for Group and Project access tokens)",
			Required:    false,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Access Level",
			},
			AllowedValues: allowedValues(ValidAccessLevels...),
		},
		"token_type": {
			Type:          framework.TypeString,
			Description:   "access token type",
			Required:      true,
			AllowedValues: allowedValues(validTokenTypes...),
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Token Type",
			},
		},
		"gitlab_revokes_token": {
			Type:        framework.TypeBool,
			Default:     false,
			Required:    false,
			Description: `Gitlab revokes the token when it's time. Vault will not revoke the token when the lease expires.`,
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Gitlab revokes token.",
			},
		},
		"config_name": {
			Type:        framework.TypeString,
			Default:     TypeConfigDefault,
			Required:    false,
			Description: "The config we use when interacting with the role, this can be specified if you want to use a specific config for the role, otherwise it uses the default one.",
			DisplayAttrs: &framework.DisplayAttributes{
				Name: "Configuration.",
			},
		},
	}
)
View Source
var (
	FieldSchemaTokenRole = map[string]*framework.FieldSchema{
		"role_name": {
			Type:        framework.TypeString,
			Description: "Role name",
			Required:    true,
		},
	}
)
View Source
var FullCommit string
View Source
var Version string = "v0.0.0-dev"

Functions

func Factory

func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error)

Factory returns expected new Backend as logical.Backend

func GitlabClientNewContext added in v0.4.0

func GitlabClientNewContext(ctx context.Context, client Client) context.Context

func HttpClientFromContext added in v0.4.0

func HttpClientFromContext(ctx context.Context) (*http.Client, bool)

func HttpClientNewContext added in v0.4.0

func HttpClientNewContext(ctx context.Context, httpClient *http.Client) context.Context

func TimeFromContext added in v0.6.1

func TimeFromContext(ctx context.Context) time.Time

func TokenName added in v0.5.0

func TokenName(role *EntryRole) (name string, err error)

func WithStaticTime added in v0.6.1

func WithStaticTime(ctx context.Context, t time.Time) context.Context

Types

type AccessLevel

type AccessLevel string

func AccessLevelParse

func AccessLevelParse(value string) (AccessLevel, error)

func (AccessLevel) String

func (i AccessLevel) String() string

func (AccessLevel) Value

func (i AccessLevel) Value() int

type Backend

type Backend struct {
	*framework.Backend
	// contains filtered or unexported fields
}

func (*Backend) GetClient added in v0.5.0

func (b *Backend) GetClient(name string) Client

func (*Backend) Invalidate

func (b *Backend) Invalidate(ctx context.Context, key string)

Invalidate invalidates the key if required

func (*Backend) SetClient

func (b *Backend) SetClient(client Client, name string)

type Client

type Client interface {
	GitlabClient(ctx context.Context) *g.Client
	Valid(ctx context.Context) bool
	CurrentTokenInfo(ctx context.Context) (*EntryToken, error)
	RotateCurrentToken(ctx context.Context) (newToken *EntryToken, oldToken *EntryToken, err error)
	CreatePersonalAccessToken(ctx context.Context, username string, userId int, name string, expiresAt time.Time, scopes []string) (*EntryToken, error)
	CreateGroupAccessToken(ctx context.Context, groupId string, name string, expiresAt time.Time, scopes []string, accessLevel AccessLevel) (*EntryToken, error)
	CreateProjectAccessToken(ctx context.Context, projectId string, name string, expiresAt time.Time, scopes []string, accessLevel AccessLevel) (*EntryToken, error)
	RevokePersonalAccessToken(ctx context.Context, tokenId int) error
	RevokeProjectAccessToken(ctx context.Context, tokenId int, projectId string) error
	RevokeGroupAccessToken(ctx context.Context, tokenId int, groupId string) error
	GetUserIdByUsername(ctx context.Context, username string) (int, error)
	GetGroupIdByPath(ctx context.Context, path string) (int, error)
	CreateGroupServiceAccountAccessToken(ctx context.Context, group string, groupId string, userId int, name string, expiresAt time.Time, scopes []string) (*EntryToken, error)
	CreateUserServiceAccountAccessToken(ctx context.Context, username string, userId int, name string, expiresAt time.Time, scopes []string) (*EntryToken, error)
	RevokeUserServiceAccountAccessToken(ctx context.Context, token string) error
	RevokeGroupServiceAccountAccessToken(ctx context.Context, token string) error
}

func GitlabClientFromContext added in v0.4.0

func GitlabClientFromContext(ctx context.Context) (Client, bool)

func NewGitlabClient

func NewGitlabClient(config *EntryConfig, httpClient *http.Client, logger hclog.Logger) (client Client, err error)

type EntryConfig added in v0.2.0

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"`
}

func (*EntryConfig) LogicalResponseData added in v0.2.0

func (e *EntryConfig) LogicalResponseData() map[string]any

func (*EntryConfig) Merge added in v0.5.0

func (e *EntryConfig) Merge(data *framework.FieldData) (warnings []string, changes map[string]string, err error)

func (*EntryConfig) UpdateFromFieldData added in v0.5.0

func (e *EntryConfig) UpdateFromFieldData(data *framework.FieldData) (warnings []string, err error)

type EntryRole added in v0.5.0

type EntryRole struct {
	RoleName            string        `json:"role_name" structs:"role_name" mapstructure:"role_name"`
	TTL                 time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"`
	Path                string        `json:"path" structs:"path" mapstructure:"path"`
	Name                string        `json:"name" structs:"name" mapstructure:"name"`
	Scopes              []string      `json:"scopes" structs:"scopes" mapstructure:"scopes"`
	AccessLevel         AccessLevel   `json:"access_level" structs:"access_level" mapstructure:"access_level,omitempty"`
	TokenType           TokenType     `json:"token_type" structs:"token_type" mapstructure:"token_type"`
	GitlabRevokesTokens bool          `json:"gitlab_revokes_token" structs:"gitlab_revokes_token" mapstructure:"gitlab_revokes_token"`
	ConfigName          string        `json:"config_name" structs:"config_name" mapstructure:"config_name"`
}

func (EntryRole) LogicalResponseData added in v0.5.0

func (e EntryRole) LogicalResponseData() map[string]any

type EntryToken

type EntryToken struct {
	TokenID            int         `json:"token_id"`
	UserID             int         `json:"user_id"`
	ParentID           string      `json:"parent_id"`
	Path               string      `json:"path"`
	Name               string      `json:"name"`
	Token              string      `json:"token"`
	TokenType          TokenType   `json:"token_type"`
	CreatedAt          *time.Time  `json:"created_at"`
	ExpiresAt          *time.Time  `json:"expires_at"`
	Scopes             []string    `json:"scopes"`
	AccessLevel        AccessLevel `json:"access_level"` // not used for personal access tokens
	RoleName           string      `json:"role_name"`
	ConfigName         string      `json:"config_name"`
	GitlabRevokesToken bool        `json:"gitlab_revokes_token"`
}

func (EntryToken) SecretResponse

func (e EntryToken) SecretResponse() (map[string]any, map[string]any)

type TokenScope

type TokenScope string

func TokenScopeParse

func TokenScopeParse(value string) (TokenScope, error)

func (TokenScope) String

func (i TokenScope) String() string

func (TokenScope) Value

func (i TokenScope) Value() string

type TokenType

type TokenType string

func TokenTypeParse

func TokenTypeParse(value string) (TokenType, error)

func (TokenType) String

func (i TokenType) String() string

func (TokenType) Value

func (i TokenType) Value() string

type Type added in v0.5.0

type Type string
const (
	TypeSaaS        Type = "saas"
	TypeDedicated   Type = "dedicated"
	TypeSelfManaged Type = "self-managed"
	TypeUnknown          = Type("")
)

func TypeParse added in v0.5.0

func TypeParse(value string) (Type, error)

func (Type) String added in v0.5.0

func (i Type) String() string

func (Type) Value added in v0.5.0

func (i Type) Value() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL