Skip to content

Device remote_addr is never persisted by the PostgreSQL store (regressed from MongoDB) #6635

Description

@gustavosbarreto

Summary

A device's remote_addr (the agent's public IP, from the X-Real-IP header) is set at authentication time but never persisted by the PostgreSQL store, so it always reads back as an empty string. The web UI device details, admin device details, and container details pages therefore never show the agent's remote address. This is a regression from the MongoDB store, which did persist it.

Root cause

AuthDevice sets device.RemoteAddr = req.RealIP (api/services/auth.go), but the PG layer has nowhere to store it:

  • The bun Device entity (api/store/pg/entity/device.go) has no remote_addr field.
  • DeviceFromModel (write path) never reads model.RemoteAddr, so the value is dropped before the INSERT.
  • DeviceToModel (read path) hardcodes RemoteAddr: "", so every read returns empty.
  • No migration adds a remote_addr column to the devices table.

The geolocation derived from the same X-Real-IP (latitude/longitude) does persist; only the address string is lost.

Regression

remote_addr was functional under MongoDB: the model carried a bson:"remote_addr" tag and the mongo store marshalled the full document, so reads returned it. It broke with the PostgreSQL store:

  • Introduced by the initial PG store (d29d4444b, 2026-02-02). The first version of the entity already lacked the field and hardcoded RemoteAddr: "".
  • Cemented when the MongoDB store was removed (bd56fb1d4, 2026-06-05), leaving PG as the sole store.

Impact

Display only. No security logic depends on it: SSH source IP, firewall rules, rate limiting, and session records use their own connection or X-Real-IP values.

  • openapi/spec/components/schemas/device.yaml advertises remote_addr but the API never populates it.
  • Web UI device details (ui/apps/console/src/pages/DeviceDetails.tsx) shows blank.
  • Admin device details (ui/apps/console/src/pages/admin/devices/AdminDeviceDetails.tsx) shows the placeholder.
  • Container details (ui/apps/console/src/pages/ContainerDetails.tsx); containers reuse the device model, so they break the same way.

Existing tests do not catch it because they assert on the service-layer model object and never round-trip through the real store.

Reproduction

  1. Connect an agent so it authenticates via POST /api/devices/auth (the gateway forwards the public IP as X-Real-IP).
  2. Accept the device, then GET /api/devices/{uid} (or open the device in the web UI).
  3. Observed: remote_addr is "". Expected: the agent's public IP, as under MongoDB.

Suggested fix

Add a remote_addr column to the devices table (migration), add a RemoteAddr string field with a bun:"remote_addr" tag to the entity, assign it in DeviceFromModel, and return entity.RemoteAddr in DeviceToModel instead of the hardcoded "". Also set it on reconnect in AuthDevice so the stored address reflects the current connection, not only the first one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions