Skip to content

feat(proxy): secret-injection outbound proxy + faccessat2 syscall fix - #279

Closed
kuangmi-bit wants to merge 2 commits into
langgenius:mainfrom
kuangmi-bit:main
Closed

feat(proxy): secret-injection outbound proxy + faccessat2 syscall fix#279
kuangmi-bit wants to merge 2 commits into
langgenius:mainfrom
kuangmi-bit:main

Conversation

@kuangmi-bit

@kuangmi-bit kuangmi-bit commented Jul 21, 2026

Copy link
Copy Markdown

Two changes in this PR

1. Secret-Injection Outbound Proxy (new)

Implements the credential-hardening proxy proposed in dify#39278. Real API keys are replaced with placeholders in the agent process and resolved at the network boundary.

Agent Process              Outbound Proxy           Internet
───────────               ──────────────           ────────
GITHUB_TOKEN=             1. Match domain          github.com ✅
  __secret:github:   →    2. Inject header    →
  GITHUB_TOKEN__           3. Audit log             evil.com ❌ (403)

New package: internal/core/proxy/

  • types.go — ProviderProfile, SecretMapping, DomainRule, InjectionRule
  • config.go — providers.yaml parsing, validation, BuildEnv
  • handler.go — InjectionHandler + InjectionRoundTripper + StripSecretsFromEnv
  • handler_test.go — 12 conformance tests (covers fixtures 1-6 from review)

Security invariants:

  • Placeholder model: agent never sees real secrets
  • Domain allowlist with suffix-attack prevention
  • Structured rejection (403, not silent-strip)
  • Path traversal prevention
  • Audit logging via structured slog

2. faccessat2 Seccomp Fix

Adds faccessat2 (syscall 439) to Python and Node.js seccomp whitelists (amd64 + arm64). Fixes "operation not permitted" on glibc ≥ 2.33 (Ubuntu 22.04+, Debian 12+, RHEL 9+).


Tests (20 total)

Proxy tests (12):
  TestPlaceholderModel          TestBase64BypassImpossible
  TestHappyPathInjection        TestRejectionOnDisallowedDomain
  TestPassthroughWithoutSecret  TestDomainMatching (9 sub-cases)
  TestNilConfigPassthrough      TestPathTraversalPrevention
  TestConfigValidation (4 sub)  TestBuildEnv
  TestStripSecretsFromEnv       TestRoundTripperInjection

Seccomp: go vet + GOARCH=arm64 go vet pass on all 4 syscall files

sg-architect added 2 commits July 21, 2026 12:11
…elists

glibc >= 2.33 uses faccessat2 instead of faccessat for access() /
faccessat() calls. Without this syscall in the seccomp whitelist,
Python os.access(), pathlib.Path.exists(), and Node.js file permission
checks fail with EACCES on modern kernels.

Affected: Python amd64/arm64, Node.js amd64/arm64

Refs: langgenius#276
…dening

Add an HTTP proxy layer that resolves placeholder env-var values into
real secrets at the network boundary, so real credentials never enter
the agent's process address space.

Design: langgenius/dify#39278

Package internal/core/proxy/:
- types: ProviderProfile, SecretMapping, DomainRule, InjectionRule
- config: LoadConfig + BuildEnv + validation (providers.yaml)
- handler: InjectionHandler (http.Handler) + InjectionRoundTripper
- StripSecretsFromEnv: replaces real secrets with placeholders

Security properties:
- Placeholder model: agent sees __secret:<provider>:<env>__
- Domain allowlist: secrets only injected for matching hosts
- Structured rejection: 403 on non-allowlisted domains (no silent-strip)
- Path traversal prevention: '..' in value_file rejects
- Audit logging: every injection/rejection via slog

Config (config.yaml):
  secret_injection:
    enabled: true
    providers_path: /etc/dify-sandbox/providers.yaml
    secret_root: /run/secrets/session-1

Conformance: 12 tests covering fixtures 1-6 from the design doc,
plus nil-config passthrough, path traversal, config validation,
BuildEnv, StripSecretsFromEnv, and RoundTripper integration.
@kuangmi-bit kuangmi-bit changed the title fix(seccomp): add faccessat2 (439) to Python and Node.js syscall whitelists feat(proxy): secret-injection outbound proxy + faccessat2 syscall fix Jul 21, 2026
@wylswz

wylswz commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Will close this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants