Skip to content
Report library
Purpose / Development

Golang Uber Fx Skill Security Audit

What the author says it does (original text)

Golang application framework using uber-go/fx — fx.New, fx.Provide, fx.Invoke, fx.Module, fx.Lifecycle hooks, fx.Annotate (name/group/As), fx.Decorate, fx.Supply, fx.Replace, fx.WithLogger, and signal-aware Run(). Apply when using or adopting uber-go/fx, when the codebase imports `go.uber.org/fx`, or when wiring services with fx.New. For raw DI without lifecycle, see `samber/cc-skills-golang@golan

Independent security check

Security risks found

Files checked
5
Risks found
5
Could it run dangerous commands?Looks for programs run straight after downloading, remote control of your computer, and hidden commands.Risks found: 1
Medium risk

Broad Go command permission can execute repository or toolchain code

Source references: 2
What we found

`Bash(go:*)` covers more than compilation and inspection; it includes code-executing commands such as `go test`, `go run`, `go generate`, and tool installation. The Skill does not require review of generators or test code before execution.

Why this matters

In an untrusted repository, these commands may run project, test, generator, or dependency code with the user's permissions, allowing access to readable files or credentials and modification of the workspace.

`Bash(go:*)` covers the full Go command surface, not only inspection or compilation. In a repository containing tests, generators, or runnable programs, an authorized agent could execute repository or toolchain code. The documented `go get` gives Go access a legitimate purpose, but the permission is not narrowed and no pre-execution review is required. Nothing here proves execution; users can restrict access to specific reviewed Go commands.

SKILL.md:18In the instructionsOpen original file
    skill-library-version: "1.24.0"allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*paths:
Show 1 other places
SKILL.md:41In the instructionsOpen original file
```bashgo get go.uber.org/fx```
Could it expose your files or keys?Looks for uploads of files containing passwords or keys, and keys written directly in the code.Risks found: 1
Medium risk

The example places an API key in the global graph as an injectable string

Source references: 3
What we found

The example reads `API_KEY` from the environment and supplies it at the top-level fx graph. Any component added to that graph that requests the matching named string can receive it; the pattern shows no module isolation, least-privilege wrapper, or log redaction.

Why this matters

If the application composes third-party, compromised, or mistaken modules, an unintended component could read the key and subsequently place it in logs or network requests. The example itself does not transmit or log the key.

This is an instructional example, not the Skill itself reading or exfiltrating credentials. It explicitly reads `API_KEY` from the environment and supplies it as a named string in the top-level Fx graph. If adopted, any component in that graph that knows the `apikey` name can request it; the example shows no scope restriction or logging safeguard. Impact depends on component trust. Users can ask for a narrow credential type or direct injection only into the API-client constructor.

references/recipes.md:218In the instructionsOpen original file
```gofunc main() {    cfg := mustLoadConfig() // parsed flags + env, before fx    secret := os.Getenv("API_KEY")    fx.New(        fx.Supply(cfg),                  // *Config available everywhere        fx.Supply(fx.Annotate(secret, fx.ResultTags(`name:"apikey"`))),        fx.Provide(NewLogger, NewAPIClient),        fx.Invoke(run),    ).Run()}
Show 2 other places
references/recipes.md:231In the instructionsOpen original file
func NewAPIClient(cfg *Config, p struct {    fx.In    APIKey string `name:"apikey"`}) *APIClient {    return &APIClient{baseURL: cfg.APIBaseURL, key: p.APIKey}}
references/recipes.md:215In the instructionsOpen original file
## fx.Supply for config and secrets```gofunc main() {    cfg := mustLoadConfig() // parsed flags + env, before fx    secret := os.Getenv("API_KEY")    fx.New(        fx.Supply(cfg),                  // *Config available everywhere        fx.Supply(fx.Annotate(secret, fx.ResultTags(`name:"apikey"`))),        fx.Provide(NewLogger, NewAPIClient),        fx.Invoke(run),    ).Run()}
Could it delete files or keep running?Looks for broad file deletion, disk overwrites, and programs set to start automatically.Risks found: 1
Low risk

Unpinned go get downloads a dependency and changes module files

Source references: 2
What we found

The installation example runs `go get go.uber.org/fx` without a version. This normally uses the network and updates the current project's go.mod/go.sum, while the resolved version may change over time.

Why this matters

The project receives lasting dependency changes and begins trusting downloaded module content. An unreviewed upgrade may also introduce compatibility or supply-chain risk.

The installation snippet recommends `go get go.uber.org/fx` without a version. When run in a module, it normally resolves a version over the network and updates dependency files, so the result can vary with time and existing module state. This is normal Go dependency installation, not concealed behavior, but it creates reproducibility and file-change risk. Users can request a pinned version and review go.mod/go.sum changes before accepting them.

SKILL.md:41In the instructionsOpen original file
```bashgo get go.uber.org/fx```
Show 1 other places
SKILL.md:35In the instructionsOpen original file
This skill is not exhaustive — refer to library documentation and code examples for more information:- For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber/cc-skills-golang@golang-pkg-go-dev` skill (`godig`), preferred over Context7 for Go package facts.- To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber/cc-skills-golang@golang-gopls` skill (`gopls`).- Context7 remains a fallback for docs not indexed on pkg.go.dev.```bashgo get go.uber.org/fx```
Could it bypass safety checks?Looks for skipped website security checks, excessive file access, or actions that skip your approval.Risks found: 2
Medium risk

The Skill requests unrestricted Git command permission

Source references: 2
What we found

`Bash(git:*)` permits every Git subcommand, although this documentation task does not require pushing, force-resetting, cleaning the worktree, or deleting branches. The files do not instruct those actions, but the permission makes them possible.

Why this matters

If the host enforces this declaration as an allowlist, an agent mistake or repository-supplied influence could rewrite local history, remove untracked files, or push through existing credentials.

The Skill declares access to every `git` subcommand, although its stated purpose is Go/Fx architecture guidance and the body does not restrict Git to read-only inspection. If the host enforces this declaration, agent-generated commands could alter branches, the worktree, or remote history; the source does not show that this happened. Users can ask the author to remove Git access or allow only named read-only subcommands.

SKILL.md:18In the instructionsOpen original file
    skill-library-version: "1.24.0"allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*paths:
Show 1 other places
SKILL.md:25In the instructionsOpen original file
# Using uber-go/fx for Application Wiring in GoApplication framework combining a reflection-based DI container (built on `uber-go/dig`) with a lifecycle, module system, signal-aware run loop, and structured event logging. For long-running services where boot order, graceful shutdown, and modular composition matter.
Low risk

The production logger example deliberately drops dependency-wiring events

Source references: 2
What we found

The custom logger returns immediately for Provided, Supplied, and Decorated events and recommends this filtering in production. This removes runtime records of how dependencies were registered or altered.

Why this matters

Operators have less evidence when investigating unintended injection, decoration, or configuration replacement. Lifecycle events and errors remain, so this does not disable all auditing.

The example logger immediately returns for Provided, Supplied, and Decorated events and explicitly recommends this filtering in production. If a user relies on Fx events to trace dependency registration or decoration changes, this reduces later audit visibility. It does not delete application data, and lifecycle events and errors remain logged, so the impact is limited to observability. Users can request retaining these events, lowering their level, or routing them to a restricted audit sink.

references/recipes.md:325In the instructionsOpen original file
func (l *ProductionLogger) LogEvent(e fxevent.Event) {    switch e.(type) {    case *fxevent.Provided, *fxevent.Supplied, *fxevent.Decorated:        return // drop the per-Provide chatter    default:        l.inner.LogEvent(e)    }}
Show 1 other places
references/recipes.md:342In the instructionsOpen original file
In production, filtering provide/decorate noise leaves only lifecycle (start/stop) events and errors — much easier to audit.
Could it mislead the AI or hide text?Checks the skill instructions for requests to ignore you, influence the report, or hide text in invisible characters.No risks found
Could it change links or payment recipients without asking?Looks for forced referral or payment changes combined with instructions to hide the change.No risks found

Inside this skill

8 instruction sections

This Skill is a Go/uber-go/fx guide covering dependency injection, lifecycle, modules, logging, and testing. The provided source contains Markdown and evaluation JSON, with no bundled executable script.

View source
SKILL.md:25In the instructionsOpen original file
# Using uber-go/fx for Application Wiring in GoApplication framework combining a reflection-based DI container (built on `uber-go/dig`) with a lifecycle, module system, signal-aware run loop, and structured event logging. For long-running services where boot order, graceful shutdown, and modular composition matter.

The guide places long-running service work in OnStart and shutdown in OnStop. Its example opens a TCP listener at the configured address, so the real exposure depends on cfg.Addr when the code is adopted.

View source
SKILL.md:94In the instructionsOpen original file
```gofunc NewHTTPServer(lc fx.Lifecycle, log *zap.Logger, cfg *Config) *http.Server {    srv := &http.Server{Addr: cfg.Addr}    lc.Append(fx.Hook{        OnStart: func(ctx context.Context) error {            ln, err := net.Listen("tcp", srv.Addr)            if err != nil { return err }            go srv.Serve(ln)         // blocking work in a goroutine            return nil        },        OnStop: func(ctx context.Context) error {            return srv.Shutdown(ctx)        },    })    return srv

The documentation states that fx constructors are lazy while Invoke triggers graph execution during startup. Constructors and hooks added to the graph therefore need the same review as application code.

View source
SKILL.md:81In the instructionsOpen original file
```gofx.New(    fx.Provide(NewLogger, NewDatabase, NewServer),  // lazy    fx.Invoke(RegisterRoutes, StartMetricsExporter), // always run during Start)````fx.Provide` registers constructors; `fx.Invoke` is the trigger — without an Invoke (directly or transitively) referencing a type, its constructor never runs.
Start here · InstructionsSKILL.md
golang-uber-fx
Lines connect the instruction file to its sections, not an observed execution order. Select a section to read the source. 5 more sections are available in the original file.

File reference map

References: 3
Files making referencesReferenced content
Lines show actual file references, not execution order. Select a node to highlight its connections and inspect the files and source locations. Dashed lines include files that still need locating.
Files and check records5 files

Coverage and gaps

Content covered in each file

These are the source ranges included in this check, not a guarantee that every issue has been resolved.

  • SKILL.mdFull text included
  • references/advanced.mdFull text included
  • references/recipes.mdFull text included
  • references/testing.mdFull text included
  • evals/evals.jsonFull text included

This report is for the version above. We read the available code and instructions without running the skill or checking extra packages it installs. This is not a promise of safety: a different version or setup may behave differently.

  • SKILL.mdInstructions
  • evals/evals.jsonSupporting file
  • references/advanced.mdSupporting file
  • references/recipes.mdSupporting file
  • references/testing.mdSupporting file

Operations mentioned in code and instructions

Connect to websites
SKILL.md:12In the instructionsOpen original file
    emoji: "🏭"    homepage: https://github.com/samber/cc-skills-golang    requires:
SKILL.md:31In the instructionsOpen original file
- [pkg.go.dev/go.uber.org/fx](https://pkg.go.dev/go.uber.org/fx)- [uber-go.github.io/fx](https://uber-go.github.io/fx/)
SKILL.md:32In the instructionsOpen original file
- [pkg.go.dev/go.uber.org/fx](https://pkg.go.dev/go.uber.org/fx)- [uber-go.github.io/fx](https://uber-go.github.io/fx/)- [github.com/uber-go/fx](https://github.com/uber-go/fx)
Run commands
SKILL.md:18In the instructionsOpen original file
    skill-library-version: "1.24.0"allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*paths:
SKILL.md:41In the instructionsOpen original file
```bashgo get go.uber.org/fx
Read keys or account settings
evals/evals.json:49In the instructionsOpen original file
    "description": "Tests fx.Supply for pre-built values (config, secrets) instead of fx.Provide with a no-op constructor",    "prompt": "In my Go application using uber-go/fx, I parse a *Config from flags and load an API_KEY environment variable in main() before calling fx.New. How should I make these available to the rest of the graph?",    "trap": "Without the skill, the model writes fx.Provide(func() *Config { return cfg }) — a redundant constructor that just returns the existing value. fx.Supply does this without the boilerplate.",
references/recipes.md:220In the instructionsOpen original file
    cfg := mustLoadConfig() // parsed flags + env, before fx    secret := os.Getenv("API_KEY")
references/recipes.md:224In the instructionsOpen original file
        fx.Supply(cfg),                  // *Config available everywhere        fx.Supply(fx.Annotate(secret, fx.ResultTags(`name:"apikey"`))),
Lines read
1,042
File checksum (to compare versions)
cb9348165f3935b49023540825b750794eac01aba97465af8851a4822afc2195