Skip to content

fix: pass registry credentials to environments#603

Merged
kmendell merged 5 commits intomainfrom
fix/env-regsitry-creds
Oct 1, 2025
Merged

fix: pass registry credentials to environments#603
kmendell merged 5 commits intomainfrom
fix/env-regsitry-creds

Conversation

@kmendell
Copy link
Member

@kmendell kmendell commented Sep 30, 2025

Fixes: #562

Summary by CodeRabbit

  • New Features

    • Supply container registry credentials for image pulls and batch update checks; credentials can be auto-injected from saved environments.
    • Environment proxy adds WebSocket support and smarter HTTP proxying with credential forwarding.
    • Background image polling automatically uses saved registry credentials.
  • Improvements

    • Clearer error responses when environment pairing fails, with guidance to resolve.
    • More informative logs during image pulls and update polling.

@kmendell kmendell requested a review from a team as a code owner September 30, 2025 20:01
@kmendell
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 30, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 30, 2025

📝 Walkthrough

Walkthrough

Adds container registry credential support across DTOs, handlers, services, and jobs. Updates PullImage and image update methods to accept external credentials. Introduces an EnvironmentMiddleware that proxies requests and injects credentials. Adjusts router/bootstrap wiring and image polling job to load credentials. Minor .env change removes AGENT_MODE default.

Changes

Cohort / File(s) Summary of changes
Env config
./.env.dev
Removed active AGENT_MODE setting; added commented placeholder.
API handlers
backend/internal/api/container_handler.go, backend/internal/api/environment_handler.go, backend/internal/api/image_handler.go, backend/internal/api/image_update_handler.go
Propagate credentials to services; update PullImage/check methods’ calls; introduce PairAgentWithBootstrap with error logging; adjust responses and request binding; wrap batch responses.
DTOs
backend/internal/dto/container_registry_dto.go, backend/internal/dto/image_dto.go, backend/internal/dto/image_update_dto.go
Add ContainerRegistryCredential type; extend ImagePullDto and BatchImageUpdateRequest with optional credentials field.
Middleware (env proxy)
backend/internal/middleware/environment_middleware.go
Add EnvironmentMiddleware with HTTP and WebSocket proxying; new NewEnvProxyMiddlewareWithParam signature; inject registry credentials into image pull/update request bodies; header forwarding and auth handling refactor.
Services — Environment
backend/internal/services/environment_service.go
Add GetDB and GetEnabledRegistryCredentials; decrypt tokens; return enabled credentials; structured logging.
Services — Image
backend/internal/services/image_service.go
Expand PullImage/getPullOptionsWithAuth to accept external credentials; prefer external creds by registry host match; standard base64 encoding; improved logging and error context.
Services — Image Update
backend/internal/services/image_update_service.go
Support external credentials in buildCredentialMap; update CheckMultipleImages/CheckAllImages signatures and flows; logging tweaks; fallback to DB registries when no external creds.
Jobs
backend/internal/job/image_polling_job.go
Add registryService dependency; load/decrypt enabled credentials; pass creds to CheckAllImages; structured logging and warnings.
Bootstrap
backend/internal/bootstrap/jobs_bootstrap.go, backend/internal/bootstrap/router_bootstrap.go
Update NewImagePollingJob call with registry service; switch to parameterized env proxy middleware; route registrations adjusted.
Callsites (pull image)
backend/internal/services/project_service.go, backend/internal/services/updater_service.go
Update PullImage invocations to include new extra credentials parameter (nil).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning Although most modifications align with credential propagation, the removal of the AGENT_MODE setting in .env.dev and the refactoring of agent-bootstrap pairing in environment_handler.go do not relate to the stated objective of applying registry credentials and introduce unrelated changes. Please extract or remove the .env.dev AGENT_MODE change and the environment_handler.go bootstrap refactor into a separate pull request so that this change set remains focused solely on implementing registry credential support.
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change in the pull request, which is enabling registry credentials to be passed into environment-related workflows, and it avoids generic phrasing or extraneous details.
Linked Issues Check ✅ Passed The code changes comprehensively implement credential propagation as described in issue #562 by fetching enabled registry credentials, decrypting them, and injecting them into environment middleware, API handlers, polling jobs, and underlying image pull and update services to ensure private registry pulls succeed on agent nodes.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/env-regsitry-creds

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/internal/services/image_service.go (1)

166-235: Use URL-safe base64 for RegistryAuth (StdEncoding is incorrect).

Dockerd expects X-Registry-Auth / RegistryAuth to be base64-url-safe (base64url); using base64.StdEncoding can cause the header to be ignored. Replace base64.StdEncoding.EncodeToString(authBytes) with base64.URLEncoding.EncodeToString(authBytes) (include padding). (docs.docker.com)

Locations: backend/internal/services/image_service.go — lines ~190 and ~226.

♻️ Duplicate comments (1)
backend/internal/job/image_polling_job.go (1)

101-133: Code duplication flagged earlier in environment_service.go.

This method duplicates credential loading logic. See the review comment on backend/internal/services/environment_service.go lines 332-361.

🧹 Nitpick comments (3)
.env.dev (1)

27-27: Fix the AGENT_MODE example in .env.dev.

The commented line shows # AGENT_MODE=f, which appears truncated—please update it to:

-# AGENT_MODE=f
+# AGENT_MODE=false

The application already defaults to false when AGENT_MODE is unset (see getBoolEnvOrDefault("AGENT_MODE", false) in backend/internal/config/config.go).

backend/internal/api/environment_handler.go (1)

101-116: Approve refactoring; recommend refining HTTP status codes

  • PairAgentWithBootstrap treats every non-200 response and network error as a generic error, leading the handler to always return 502. To improve API semantics, consider refactoring so the handler can distinguish cases:
    • Return 401/403 when the agent responds with an authentication error
    • Return 503 for timeouts or agent unavailability
    • Fallback to 502 for other gateway/network failures
backend/internal/services/environment_service.go (1)

328-330: Consider whether exposing the database connection is necessary.

Exposing GetDB() breaks encapsulation and may allow callers to bypass service-layer business logic. If this is only needed for specific operations, consider adding targeted methods instead.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a8f049 and 29f1bc7.

📒 Files selected for processing (17)
  • .env.dev (1 hunks)
  • backend/internal/api/container_handler.go (1 hunks)
  • backend/internal/api/environment_handler.go (2 hunks)
  • backend/internal/api/image_handler.go (1 hunks)
  • backend/internal/api/image_update_handler.go (2 hunks)
  • backend/internal/bootstrap/jobs_bootstrap.go (1 hunks)
  • backend/internal/bootstrap/router_bootstrap.go (1 hunks)
  • backend/internal/dto/container_registry_dto.go (1 hunks)
  • backend/internal/dto/image_dto.go (1 hunks)
  • backend/internal/dto/image_update_dto.go (1 hunks)
  • backend/internal/job/image_polling_job.go (5 hunks)
  • backend/internal/middleware/environment_middleware.go (5 hunks)
  • backend/internal/services/environment_service.go (3 hunks)
  • backend/internal/services/image_service.go (3 hunks)
  • backend/internal/services/image_update_service.go (4 hunks)
  • backend/internal/services/project_service.go (1 hunks)
  • backend/internal/services/updater_service.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-23T20:31:03.836Z
Learnt from: CR
PR: ofkm/arcane#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-23T20:31:03.836Z
Learning: Applies to internal/middleware/**/*.go : Implement authentication middleware (JWT/OIDC) and correct CORS handling

Applied to files:

  • backend/internal/middleware/environment_middleware.go
🪛 GitHub Actions: Run Backend Linter
backend/internal/middleware/environment_middleware.go

[error] 139-139: cognitive complexity 31 of func (*EnvironmentMiddleware).proxyHTTP is high (> 30) (gocognit)

🪛 GitHub Check: Run Golangci-lint
backend/internal/middleware/environment_middleware.go

[failure] 253-253:
error is not nil (line 251) but it returns nil (nilerr)


[failure] 139-139:
cognitive complexity 31 of func (*EnvironmentMiddleware).proxyHTTP is high (> 30) (gocognit)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: test
  • GitHub Check: build
  • GitHub Check: Analyze (go)
🔇 Additional comments (12)
backend/internal/api/environment_handler.go (1)

4-4: LGTM: Structured logging import.

The addition of log/slog is appropriate for the structured logging introduced in the error handling below.

backend/internal/dto/image_dto.go (1)

12-13: LGTM! Credentials field enables registry authentication.

The addition of the Credentials field to ImagePullDto aligns with the PR objective to pass registry credentials for private image pulls. The omitempty tag correctly makes this field optional.

backend/internal/dto/image_update_dto.go (1)

46-47: LGTM! Credentials field supports batch update authentication.

The addition of the Credentials field to BatchImageUpdateRequest enables passing registry credentials for batch image update operations. The omitempty tag correctly makes this field optional.

backend/internal/dto/container_registry_dto.go (1)

16-21: LGTM! New credential type supports registry authentication.

The ContainerRegistryCredential type provides the necessary fields for passing registry credentials. The binding:"required" tags on URL, Username, and Token ensure these fields are validated during request binding.

backend/internal/bootstrap/jobs_bootstrap.go (1)

26-26: Constructor signature matches. The call to NewImagePollingJob correctly passes appServices.ContainerRegistry as a *services.ContainerRegistryService, aligning with the constructor’s fourth parameter.

backend/internal/api/image_handler.go (1)

127-127: LGTM! Credentials are now propagated to the image pull operation.

The updated call correctly passes req.Credentials to the service layer, enabling external registry credentials for image pulls.

backend/internal/api/image_update_handler.go (1)

101-101: LGTM! Credentials are now passed to batch image update checks.

The update correctly propagates credentials from the request to the service layer.

backend/internal/job/image_polling_job.go (2)

21-27: LGTM! Registry service dependency added to support credential loading.

The constructor now accepts registryService to enable loading of registry credentials for image update checks.


64-75: LGTM! Credentials are now loaded and passed to image update checks.

The job now loads registry credentials before checking images, with appropriate error handling that logs failures but continues operation.

backend/internal/services/image_service.go (3)

100-100: LGTM! Image pull now accepts external credentials.

The signature update enables passing registry credentials from callers, supporting the credential propagation flow introduced in this PR.


107-116: Good observability for credential handling.

The debug logging helps trace credential usage without exposing sensitive tokens, and the warning on auth failures provides visibility into configuration issues.


171-197: LGTM! External credentials take precedence with proper fallback.

The logic correctly:

  • Iterates through external credentials first
  • Matches credentials by normalized registry host
  • Returns early on match
  • Falls back to database credentials if no match

The host normalization ensures consistent matching across different URL formats.

@kmendell kmendell merged commit e04d6c9 into main Oct 1, 2025
11 checks passed
@kmendell kmendell deleted the fix/env-regsitry-creds branch October 1, 2025 00:19
@petrm
Copy link

petrm commented Oct 1, 2025

I pulled release 1.3 and still seeing the broken behavior. Does this need some configuration?

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.

🐞 Bug: Update check fails with private registry on agent nodes

2 participants