Documentation
¶
Overview ¶
Package dependencyfirewall implements the MCP tool for GitLab's Dependency Firewall package evaluation endpoint.
One handler wraps the single public endpoint:
- EvaluatePackage — POST /api/v4/projects/:id/dependency_firewall/evaluate
The endpoint evaluates one package coordinate (ecosystem, name, version) against the project's Dependency Firewall policies and answers with an outcome of allowed, warned or blocked, plus the policy that produced a warned or blocked outcome.
Tier and availability, both taken from the API page rather than inferred: "Tier: Premium, Ultimate" and "Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated", so the action is gated at premium and is not GitLab.com only. The API itself was "Introduced in GitLab 19.4 with a feature flag named `dependency_firewall_phase1`. Disabled by default", and it is an experiment. An instance that does not have the flag enabled answers 404 for every project, which is indistinguishable from a project the token cannot see, so EvaluatePackage turns a 404 into an informational result naming the flag instead of a bare error. That is the shape internal/tools/orbit already uses for the equally experimental Knowledge Graph API.
Index ¶
Constants ¶
const ActionEvaluate = "project.dependency_firewall_evaluate"
ActionEvaluate is the canonical action ID. The evaluate endpoint is projected under the gitlab_project meta-tool, so its domain prefix is "project" (see actioncatalog DomainFromToolName). One evaluate call is not a domain, and a catalog group of one would cost every Premium instance a meta-tool holding a single action.
const FeatureFlag = "dependency_firewall_phase1"
FeatureFlag is the GitLab feature flag the Dependency Firewall API is served behind. It is named in the not-found hint so a caller on an instance without it is told why the endpoint is missing rather than left with a bare 404.
Variables ¶
var Ecosystems = []string{ string(gitlab.DependencyFirewallEcosystemCargo), string(gitlab.DependencyFirewallEcosystemComposer), string(gitlab.DependencyFirewallEcosystemConan), string(gitlab.DependencyFirewallEcosystemGem), string(gitlab.DependencyFirewallEcosystemGolang), string(gitlab.DependencyFirewallEcosystemMaven), string(gitlab.DependencyFirewallEcosystemNPM), string(gitlab.DependencyFirewallEcosystemNuGet), string(gitlab.DependencyFirewallEcosystemPub), string(gitlab.DependencyFirewallEcosystemPyPI), string(gitlab.DependencyFirewallEcosystemSwift), }
Ecosystems lists every package ecosystem the Dependency Firewall evaluates, in the order the API documentation lists them. It is the source for both the input schema enum and the runtime validation, so the two cannot drift.
The values are read off client-go's DependencyFirewallEcosystemValue constants, which v2.61.0 widened from the original four (maven, npm, pypi, gem) with composer, conan, golang, nuget, cargo, swift and pub.
Functions ¶
func ActionSpecs ¶
func ActionSpecs(client *gitlabclient.Client) []toolutil.ActionSpec
ActionSpecs returns the canonical spec for the Dependency Firewall package evaluation action.
The action is gated at premium because the API page states "Tier: Premium, Ultimate", and it is not marked GitLab.com only because the same page states "Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated".
It is read-only despite being a POST: evaluating a coordinate against the project's policies returns a verdict and changes nothing, so --read-only and a read_api token both keep it.
func FormatEvaluatePackageMarkdown ¶
func FormatEvaluatePackageMarkdown(out EvaluatePackageOutput) string
FormatEvaluatePackageMarkdown renders a Dependency Firewall verdict.
The outcome leads, because it is the answer to the only question the caller asked, and the reason follows when GitLab gave one. An allowed outcome is reported as "no policy rule matched" rather than "the package is safe": the API allows a package that is simply absent from the package metadata database, and a formatter that called that safe would be inventing an assurance nobody made.
Types ¶
type EvaluatePackageInput ¶
type EvaluatePackageInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
Ecosystem string `` /* 134-byte string literal not displayed */
Name string `` /* 207-byte string literal not displayed */
Version string `json:"version" jsonschema:"Package version, maximum 255 characters,required"`
}
EvaluatePackageInput holds the parameters for evaluating one package coordinate against a project's Dependency Firewall policies.
The three coordinate fields map one-to-one onto client-go's EvaluatePackageOptions, which carries exactly Ecosystem, Name and Version. The documented optional `operation` attribute (download or upload) has no field on that options struct, so it cannot be sent through the wrapper; the gap is recorded in docs/development/upstream-bugs.md. GitLab defaults the attribute to download.
type EvaluatePackageOutput ¶
type EvaluatePackageOutput struct {
toolutil.HintableOutput
// Outcome is allowed, warned or blocked. An allowed outcome means no
// policy rule matched the package, which is not an assertion that
// GitLab holds vulnerability or license data for it: a package absent
// from the package metadata database is also allowed.
Outcome string `json:"outcome"`
// Reason names the policy that produced a warned or blocked outcome,
// and is null for an allowed one.
Reason *string `json:"reason"`
}
EvaluatePackageOutput is the outcome of a Dependency Firewall evaluation.
It carries both fields of client-go's PackageEvaluation. Reason stays a pointer, as it is upstream: GitLab answers null when the outcome is allowed, and a pointer keeps "no reason was given" distinguishable from "the reason was the empty string".
func EvaluatePackage ¶
func EvaluatePackage(ctx context.Context, client *gitlabclient.Client, input EvaluatePackageInput) (EvaluatePackageOutput, error)
EvaluatePackage evaluates a single package coordinate against a project's Dependency Firewall policies.
Endpoint: POST /api/v4/projects/:id/dependency_firewall/evaluate. The call changes nothing on the instance, so the action is read-only even though the verb is POST.
A 404 is left for the action route to turn into an informational result naming the feature flag: on an instance where dependency_firewall_phase1 is off every project answers 404, and the bare status alone would read as "this project does not exist".