Skip to content
Report library
Purpose / Development

Golang Samber Do Skill Security Audit

What the author says it does (original text)

Dependency injection in Golang using samber/do — service containers, lifecycle management, scopes, health checks, graceful shutdown, and module organization. Apply when using or adopting samber/do, when the codebase imports github.com/samber/do or github.com/samber/do/v2, or when refactoring manual constructor injection into a DI container.

Independent security check

Do not install or run it yet

Files checked
4
Risks found
4
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

The full startup example can panic on dependency failure and discards server startup errors

Source references: 5
What we found

The guide states that `MustInvoke` panics on error, yet the complete `main` example uses it at the composition root, where no enclosing `Invoke` converts that panic back to an error. It also calls `ListenAndServe` in a goroutine and ignores its return value.

Why this matters

A provider initialization failure can terminate the process. A bind or listener failure can instead leave a process waiting for a signal while serving no HTTP traffic, harming availability and failure detection.

The guide says `MustInvoke` panics on failure and is safe inside providers when an enclosing `Invoke` converts that panic to an error. The full `main` example instead calls it directly at the composition root, so initialization failure can terminate the process. It also discards `ListenAndServe`'s error in a goroutine; on a bind/listen failure, the process may remain waiting for shutdown while serving nothing. Users can request explicit handling of resolution and server-start errors.

SKILL.md:103In the instructionsOpen original file
// (e.g. an HTTP handler that must degrade gracefully instead of crashing)db, err := do.Invoke[Database](injector)// MustInvoke panics on error — preferred in providers, recovered by do.Invoke on the parent calldb := do.MustInvoke[Database](injector)```
Show 4 other places
SKILL.md:185In the instructionsOpen original file
    server := do.MustInvoke[*http.Server](injector)    go server.ListenAndServe()    _ = injector.ShutdownOnSignalsWithContext(context.Background(), os.Interrupt)}
SKILL.md:223In the instructionsOpen original file
| -------------------------- | ----------------------------------------- || `do.Invoke[T]()`           | Get service (with error)                  || `do.InvokeNamed[T]()`      | Get named service                         || `do.InvokeAs[T]()`         | Get first service matching interface      || `do.InvokeStruct[T]()`     | Inject into struct fields using tags      || `do.MustInvoke[T]()`       | Get service (panic on error)              || `do.MustInvokeNamed[T]()`  | Get named service (panic on error)        |
SKILL.md:101In the instructionsOpen original file
```go// Invoke with error handling — reserve for call sites outside the DI graph// (e.g. an HTTP handler that must degrade gracefully instead of crashing)db, err := do.Invoke[Database](injector)// MustInvoke panics on error — preferred in providers, recovered by do.Invoke on the parent calldb := do.MustInvoke[Database](injector)```Inside a provider function, always use `do.MustInvoke` (or `MustInvokeAs`/`MustInvokeNamed`/`MustInvokeStruct`) rather than the error-returning variant:- A provider already returns `(T, error)`, so propagating a dependency failure with `do.Invoke` costs an extra `if err != nil { return nil, err }` on every call.- `do.MustInvoke` panics instead, but samber/do correctly catches and recovers that panic at the enclosing `Invoke` call and converts it back into a regular error — this recover happens inside the library itself, not in caller code, so `MustInvoke` is safe to use inside providers.- The failure still surfaces as an error at the composition root, just without the manual boilerplate in every provider.
SKILL.md:174In the instructionsOpen original file
## Full Application Setup```gofunc main() {    injector := do.New(        infrastructure.Package,        repository.Package,        service.Package,        transport.Package,    )    server := do.MustInvoke[*http.Server](injector)    go server.ListenAndServe()    _ = injector.ShutdownOnSignalsWithContext(context.Background(), os.Interrupt)}```
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
High risk

The “request-scoped” example creates one scope, which may share state across users' requests

Source references: 2
What we found

Under “Request-scoped services,” the advanced guide calls `root.Scope("request")` only once and registers services in it, without showing creation and disposal per request. The included evaluation explicitly expects a new scope per request, so the live guidance conflicts with its intended isolation model.

Why this matters

If an application copies this pattern and reuses the scope, lazy request contexts, current-user objects, or other stateful services may be shared across requests, causing identity confusion or one user's data to enter another user's processing.

The guide labels a single, one-time `root.Scope("request")` as request-scoped without saying that a distinct scope must be created and cleaned up for every request. If a user creates it at startup and reuses it, mutable current-user or request-context services could be shared across concurrent users. The eval is not executable behavior, but it confirms the intended model is one scope per request. Users can ask for a complete handler example showing per-request creation and cleanup.

references/advanced.md:49In the instructionsOpen original file
```goroot := do.New()// Global/stateless services in rootdo.Provide(root, NewConfig)do.Provide(root, NewLogger)// Request-scoped servicesrequestScope := root.Scope("request")do.Provide(requestScope, NewRequestContext)```
Show 1 other places
evals/evals.json:61In the instructionsOpen original file
    "description": "Tests whether the model uses scopes to organize services by lifecycle and visibility",    "prompt": "In my Go web app using samber/do, I have global services (config, logger) and per-request services (request context, current user). How do I prevent per-request services from being shared across requests?",    "trap": "Without the skill, the model registers everything in the root container, leading to shared per-request state across concurrent requests",    "assertions": [      {"id": "5.1", "text": "Uses do.Scope to create child scopes for per-request services"},      {"id": "5.2", "text": "Registers global/stateless services (config, logger) in the root container"},      {"id": "5.3", "text": "Creates a new scope per request for request-scoped services"},      {"id": "5.4", "text": "Child scope services can access parent (root) services"},      {"id": "5.5", "text": "Does NOT register request-scoped services in the root container"}    ]
Could it delete files or keep running?Looks for broad file deletion, disk overwrites, and programs set to start automatically.Risks found: 1
Medium risk

Unpinned `go get -u` broadens dependency updates and project-file changes

Source references: 1
What we found

The installation step explicitly uses `-u` without pinning a version. Besides fetching the target package, this permits Go to update selected module dependencies and rewrite `go.mod` and `go.sum`; the exact changes depend on the existing module graph.

Why this matters

A user intending only to add the DI library may receive additional version changes, new transitive code, or compatibility regressions, increasing supply-chain and build risk.

This is an active installation instruction using unpinned `go get -u`. If run, Go may upgrade the target and related modules in the current module graph and rewrite `go.mod` and `go.sum`; the exact changes depend on the project. Installing the DI library fits the stated purpose, but `-u` broadens the modification scope. Users can request a reviewed pinned version without `-u` and inspect module-file changes first.

SKILL.md:41In the instructionsOpen original file
Install v2 — v1 is superseded and lacks the generics-based container, scopes, and lifecycle hooks documented below, so v1-era guidance misleads on every API in this skill:```bashgo get -u github.com/samber/do/v2```
Could it bypass safety checks?Looks for skipped website security checks, excessive file access, or actions that skip your approval.Risks found: 1
Low risk

The Skill has arbitrary git and agent-spawning permissions beyond its demonstrated DI workflow

Source references: 3
What we found

The permission declaration includes `Bash(git:*)`, `Agent`, `WebFetch`, and file writes. Editing Go files and consulting documentation fit the purpose, but the shown workflow does not require arbitrary git operations or spawning other agents.

Why this matters

If the agent is influenced by a mistaken instruction or subsequently retrieved untrusted content, these permissions could widen the effect to repository-history or remote changes, network-fetched content, and delegated work. The supplied evidence does not show that any such action occurred.

The active tool metadata permits file writes, any `git` subcommand, agent launch, and web retrieval. Editing Go files and consulting library documentation fit the DI purpose, but the shown workflow does not establish a need for unrestricted Git or agent access. If the host enforces these declarations, prompt manipulation or mistakes could alter repository state, expose project content through network requests, or broaden delegated execution. Users can request least-privilege metadata and disable Git, agent, or network access unless specifically needed.

SKILL.md:18In the instructionsOpen original file
    skill-library-version: "2.0.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:  - "**/*.go"---
Show 2 other places
SKILL.md:2In the instructionsOpen original file
---name: golang-samber-dodescription: "Dependency injection in Golang using samber/do — service containers, lifecycle management, scopes, health checks, graceful shutdown, and module organization. Apply when using or adopting samber/do, when the codebase imports github.com/samber/do or github.com/samber/do/v2, or when refactoring manual constructor injection into a DI container."user-invocable: truelicense: MITcompatibility: Designed for Claude Code, Codex or similar harness, and for projects using Golang.metadata:
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.
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

7 instruction sections

The Skill guides the agent to add samber/do v2 to a Go project and register, resolve, and shut down services at the composition root; its installation command accesses the network and changes the project's Go module files.

View source
SKILL.md:41In the instructionsOpen original file
Install v2 — v1 is superseded and lacks the generics-based container, scopes, and lifecycle hooks documented below, so v1-era guidance misleads on every API in this skill:```bashgo get -u github.com/samber/do/v2```
SKILL.md:177In the instructionsOpen original file
```gofunc main() {    injector := do.New(        infrastructure.Package,        repository.Package,        service.Package,        transport.Package,    )    server := do.MustInvoke[*http.Server](injector)    go server.ListenAndServe()    _ = injector.ShutdownOnSignalsWithContext(context.Background(), os.Interrupt)}

It also provides examples for child scopes, lifecycle handling, health checks, struct injection, and cloning a container to override test dependencies.

View source
references/advanced.md:21In the instructionsOpen original file
## Scopes (Module Tree)Scopes SHOULD be used to organize services by module:```goroot := do.New()// Register shared services in rootdo.Provide(root, func(i do.Injector) (Database, error) {    return &Database{}, nil})// Create child scopeapiScope := root.Scope("api")// Services in apiScope can access root servicesdo.Provide(apiScope, func(i do.Injector) (UserService, error) {    db := do.MustInvoke[Database](i) // from root    return &userService{db: db}, nil
references/testing.md:8In the instructionsOpen original file
```gofunc TestUserService(t *testing.T) {    // Create test container by cloning main container    testInjector := mainInjector.Clone()    // Override with mocks    mockDB := &MockDatabase{}    do.OverrideValue(testInjector, mockDB)    // Test with mocked dependencies    service := do.MustInvoke[UserService](testInjector)    // ... test code

The manifest grants file read/write access, arbitrary git subcommands, scoped Go commands, web fetching, and agent spawning; the body does not instruct any specific git operation.

View source
SKILL.md:18In the instructionsOpen original file
    skill-library-version: "2.0.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:  - "**/*.go"---
Start here · InstructionsSKILL.md
golang-samber-do
Lines connect the instruction file to its sections, not an observed execution order. Select a section to read the source.

File reference map

References: 2
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 records4 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/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/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/github.com/samber/do/v2](https://pkg.go.dev/github.com/samber/do/v2)- [do.samber.dev](https://do.samber.dev)
SKILL.md:32In the instructionsOpen original file
- [pkg.go.dev/github.com/samber/do/v2](https://pkg.go.dev/github.com/samber/do/v2)- [do.samber.dev](https://do.samber.dev)- [github.com/samber/do/v2](https://github.com/samber/do)
Run commands
SKILL.md:18In the instructionsOpen original file
    skill-library-version: "2.0.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:43In the instructionsOpen original file
```bashgo get -u github.com/samber/do/v2
Lines read
667
File checksum (to compare versions)
b02f906d1703ceff0b63a68ea19c30e62c411adc03389bc5b2a4351df239a667