Skip to content

ForgeConnection

How the Software Factory reaches a git forge other than github.com: a bot account's access token on Gitea, Forgejo or GitLab (or GitHub Enterprise Server). Fields, YAML, HCL and CLI samples, and how apply treats it.

Checked against config-schemas@v1.15.0, terraform-provider-resolve@82cb23c, cli@v4.9.1

How the Software Factory reaches a git forge other than github.com: a bot account’s access token on Gitea, Forgejo or GitLab (or GitHub Enterprise Server), or a GitHub App registered on a GitHub Enterprise Server. github.com is reached through the Vulnetix GitHub App instead (GitHubInstallation). Apply asks the forge what it is and checks the credential can list repositories before anything is stored; the credential and the webhook secret are kept in the tenant’s vault as a connector secret, never in the document, an export or a plan. The type, host and account identify the connection and cannot change: declare a new connection instead. Deleting the document removes the webhooks the factory created, revokes the stored credential and marks the connection deleted; managed scope and repository settings rows are kept, read-only, as for an uninstalled App.

apiVersion vulnetix.com/v1
kind ForgeConnection
Group Integrations
Status Served. The config engine plans and applies it.
Objects per tenant many, keyed by metadata.name
Token and role An owner or admin session, or a vmt_ config management token with the owner or admin role that lists ForgeConnection in its kinds. See Management tokens.
Secret fields spec.token, spec.app.privateKey, spec.oauth.clientSecret: read on the client from valueFrom, sent once, never exported or shown in a plan
Terraform resource vulnetix_forge_connection, imported by name (see Terraform and OpenTofu)
CLI vulnetix config apply, CLI v3.168.0 and later.
Pinned schema v1.15.0/ForgeConnection.schema.json
Newest schema latest/ForgeConnection.schema.json
First released in v1.5.0
Print the built-in copy vulnetix config schema ForgeConnection

Minimal

Only the fields the kind requires. From examples/ForgeConnection/minimal.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/ForgeConnection.schema.json
apiVersion: vulnetix.com/v1
kind: ForgeConnection
metadata:
  name: codeberg
spec:
  type: forgejo
  host: codeberg.org

HCL (resource vulnetix_forge_connection)

# Only the arguments the kind requires. From config-schemas examples/ForgeConnection/minimal.yaml.

resource "vulnetix_forge_connection" "codeberg" {
  name = "codeberg"
  host = "codeberg.org"
  type = "forgejo"
}

CLI (applies it)

export VULNETIX_CONFIG_TOKEN=vmt_...   # a config management token
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/ForgeConnection.schema.json
apiVersion: vulnetix.com/v1
kind: ForgeConnection
metadata:
  name: codeberg
spec:
  type: forgejo
  host: codeberg.org
EOF

Advanced

Every field the kind supports, with a when expression where it takes one. From examples/ForgeConnection/advanced.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/ForgeConnection.schema.json
# A self-managed GitLab group reached with a bot token, with an OAuth
# application so members can link their own GitLab accounts, and a GitHub
# Enterprise Server reached through a GitHub App registered on it.
apiVersion: vulnetix.com/v1
kind: ForgeConnection
metadata:
  name: gitlab-platform
  labels:
    team: platform
  annotations:
    note: The bot account is vulnetix-bot, a Developer in the platform group.
spec:
  type: gitlab
  host: gitlab.example.com
  apiBase: https://gitlab.example.com/api/v4
  account: platform
  token: { env: VULNETIX_GITLAB_TOKEN }
  oauth:
    clientId: 6f1e2d3c4b5a69788796a5b4c3d2e1f0
    clientSecret: { env: VULNETIX_GITLAB_OAUTH_SECRET }
---
apiVersion: vulnetix.com/v1
kind: ForgeConnection
metadata:
  name: ghes-acme
spec:
  type: ghes
  host: github.acme.example
  account: acme
  app:
    appId: 12
    appSlug: vulnetix
    installationId: 3
    privateKey: { env: VULNETIX_GHES_APP_KEY }

HCL (resource vulnetix_forge_connection)

# Every argument the kind supports. From config-schemas examples/ForgeConnection/advanced.yaml.

variable "gitlab_platform_oauth_client_secret" {
  type      = string
  sensitive = true
  ephemeral = true
}
variable "gitlab_platform_token" {
  type      = string
  sensitive = true
  ephemeral = true
}
variable "ghes_acme_app_private_key" {
  type      = string
  sensitive = true
  ephemeral = true
}

resource "vulnetix_forge_connection" "gitlab_platform" {
  name     = "gitlab-platform"
  account  = "platform"
  api_base = "https://gitlab.example.com/api/v4"
  host     = "gitlab.example.com"
  oauth = {
    client_id                = "6f1e2d3c4b5a69788796a5b4c3d2e1f0"
    client_secret_wo         = var.gitlab_platform_oauth_client_secret
    client_secret_wo_version = 1
  }
  token_wo         = var.gitlab_platform_token
  token_wo_version = 1
  type             = "gitlab"
  labels = {
    team = "platform"
  }
  annotations = {
    note = "The bot account is vulnetix-bot, a Developer in the platform group."
  }
}

resource "vulnetix_forge_connection" "ghes_acme" {
  name    = "ghes-acme"
  account = "acme"
  app = {
    app_id                 = 12
    app_slug               = "vulnetix"
    installation_id        = 3
    private_key_wo         = var.ghes_acme_app_private_key
    private_key_wo_version = 1
  }
  host = "github.acme.example"
  type = "ghes"
}

CLI (applies it)

export VULNETIX_CONFIG_TOKEN=vmt_...   # a config management token
export VULNETIX_GITLAB_TOKEN=...   # read on this machine by valueFrom, never written to the document
export VULNETIX_GITLAB_OAUTH_SECRET=...   # read on this machine by valueFrom, never written to the document
export VULNETIX_GHES_APP_KEY=...   # read on this machine by valueFrom, never written to the document
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/ForgeConnection.schema.json
# A self-managed GitLab group reached with a bot token, with an OAuth
# application so members can link their own GitLab accounts, and a GitHub
# Enterprise Server reached through a GitHub App registered on it.
apiVersion: vulnetix.com/v1
kind: ForgeConnection
metadata:
  name: gitlab-platform
  labels:
    team: platform
  annotations:
    note: The bot account is vulnetix-bot, a Developer in the platform group.
spec:
  type: gitlab
  host: gitlab.example.com
  apiBase: https://gitlab.example.com/api/v4
  account: platform
  token: { env: VULNETIX_GITLAB_TOKEN }
  oauth:
    clientId: 6f1e2d3c4b5a69788796a5b4c3d2e1f0
    clientSecret: { env: VULNETIX_GITLAB_OAUTH_SECRET }
---
apiVersion: vulnetix.com/v1
kind: ForgeConnection
metadata:
  name: ghes-acme
spec:
  type: ghes
  host: github.acme.example
  account: acme
  app:
    appId: 12
    appSlug: vulnetix
    installationId: 3
    privateKey: { env: VULNETIX_GHES_APP_KEY }
EOF

Fields

Paths use dots for nesting and [] for the items of a list. Required means required whenever the parent object is present. A default is what the server uses when the field is left out.

Field Type Required Default Allowed values Secret Description
apiVersion string yes exactly vulnetix.com/v1 The document format version. Every kind in this release is vulnetix.com/v1.
kind string yes exactly ForgeConnection Always ForgeConnection.
metadata object yes no other keys
metadata.name string yes pattern ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ The object’s name, unique per kind within a tenant. It is the natural key: plan, apply, export and the Terraform provider all address an object by kind and name.
metadata.org string no format uuid The tenant (organization UUID) the document belongs to. When set, plan and apply refuse to run against any other tenant.
metadata.labels object no map of string to string (length 0 to 256); keys match ^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$ Free key/value labels. Stored with the object, never interpreted by the server.
metadata.annotations object no map of string to string (length 0 to 4096) Free key/value notes for people and tools, such as a ticket link.
spec object yes no other keys
spec.type string yes ghes, gitea, forgejo, gitlab The forge software. Gitea and Forgejo speak one API, so the server keeps whichever of the two the host answers as, and a plan does not count the other spelling as a change.
spec.host string yes not github.com, www.github.com, api.github.com; pattern ^[A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?(:[0-9]{1,5})?$; length 1 to 253 The forge’s host name, with a port when it is not 443: git.example.com, codeberg.org, gitlab.example.com:8443. No scheme or path. It is stored lower case.
spec.apiBase string no pattern ^https://; format uri; length 0 to 1024 The REST base, when it is not the forge’s default (https:///api/v4 for GitLab, /api/v1 for Gitea and Forgejo, /api/v3 for GitHub Enterprise Server). It must be https on the same host.
spec.account string no length 1 to 255 The organisation, group or user the connection is for. Left out, the connection covers every repository the credential reaches.
spec.token object no 1 to 1 keys; no other keys yes Where the client reads the bot account’s access token. Required when the connection is created, unless app is set; left out afterwards, the stored token is kept. The token is checked against the forge at apply.
spec.token.env string no pattern ^[A-Za-z_][A-Za-z0-9_]*$ Name of an environment variable.
spec.token.file string no length 1 to any Path to a file holding the value. Trailing newlines are trimmed.
spec.app object no no other keys A GitHub App registered on the GitHub Enterprise Server, instead of a bot token. ghes only.
spec.app.appId integer yes >= 1 The App’s id on the server.
spec.app.appSlug string no pattern ^[a-z0-9][a-z0-9-]{0,99}$ The App’s slug, which names the bot that commits ([bot]).
spec.app.installationId integer yes >= 1 The App’s installation on the account.
spec.app.privateKey object no 1 to 1 keys; no other keys yes Where the client reads the App’s private key (PEM). Required when the connection is created; left out afterwards, the stored key is kept.
spec.app.privateKey.env string no pattern ^[A-Za-z_][A-Za-z0-9_]*$ Name of an environment variable.
spec.app.privateKey.file string no length 1 to any Path to a file holding the value. Trailing newlines are trimmed.
spec.oauth object no no other keys An OAuth application made on the forge, so that members can link their own forge account to the connection: their commits from a factory page then carry an email the forge verifies, and their signing key can be added to their forge account. Each member signs in for themselves from the console. Register the redirect URI the object’s status reports (status.oauthRedirectUri) on the application. Left out, the application stored on the connection is removed.
spec.oauth.clientId string yes length 1 to 200 The application’s client id.
spec.oauth.clientSecret object no 1 to 1 keys; no other keys yes Where the client reads the application’s client secret. Required when sign-in is first set up; left out afterwards, the stored secret is kept.
spec.oauth.clientSecret.env string no pattern ^[A-Za-z_][A-Za-z0-9_]*$ Name of an environment variable.
spec.oauth.clientSecret.file string no length 1 to any Path to a file holding the value. Trailing newlines are trimmed.

Applying this kind

  • Command. vulnetix config apply -f <file>; the CLI line above says from which release. Plan first with vulnetix config plan: it shows each object as create, update, delete or no change, with a planHash that apply then holds to. Apply writes in one transaction.
  • Manager. Each object records the manager that applied it (terraform, console or gitops:<repo>). --prune deletes only objects its own manager owns. See The manager and the config engine.
  • Status. connection, botLogin and version. The phases the engine reports are explained under status phases.

How apply treats it

The console’s create and update writers, now transaction scoped. A bot token or a GitHub Enterprise Server App key is a valueFrom secret, kept as the console keeps it. GitHub.com is refused: use GitHubInstallation.

Terraform and OpenTofu

The resource is vulnetix_forge_connection in the vulnetix/resolve provider. Its arguments are the spec in snake case, beside name, labels and annotations from metadata. The Minimal and Advanced HCL are above. The provider’s own reference is vulnetix_forge_connection.

Import an object that already exists by its name:

# Import an existing ForgeConnection by its name (metadata.name).
terraform import vulnetix_forge_connection.codeberg codeberg

A secret is two arguments, never stored in the plan or the state: token_wo (write-only) and token_wo_version, private_key_wo (write-only) and private_key_wo_version, client_secret_wo (write-only) and client_secret_wo_version. Change the version number to send a new value. See Secrets.

Install, authentication and how state is read: Terraform and OpenTofu.

Check a file with vulnetix config validate -f <file>. See Validate documents. In an editor, start the file with the schema comment.

Edit this pageSources: config-schemas/schemas/ForgeConnection.schema.json, config-schemas/schemas/common.schema.json, config-schemas/examples/ForgeConnection/minimal.yaml, config-schemas/examples/ForgeConnection/advanced.yaml, terraform-provider-resolve/examples/resources/vulnetix_forge_connection/minimal.tf, terraform-provider-resolve/examples/resources/vulnetix_forge_connection/advanced.tf, vdb-site/docs/platform-iac-engine.md, vdb-site/api/internal/handler/config_engine_kinds.go, vdb-site/api/internal/config/forgeconnection.go
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.