Environment Variable Expansion in PostgreSQL DSN Configuration for AgentsView

AgentsView does not perform automatic environment variable expansion in PostgreSQL DSN strings; the application reads the AGENTSVIEW_PG_URL environment variable verbatim and passes it directly to the pgx driver without processing ${VAR} or $VAR placeholders.

When configuring database connections for the kenn-io/agentsview repository, understanding how the PostgreSQL connection string is processed is critical for secure credential management. The application relies on the AGENTSVIEW_PG_URL environment variable to establish database connectivity, but unlike some frameworks, it does not interpolate environment variables within the DSN itself. This behavior impacts how you structure your deployment configuration and handle sensitive credentials.

How AgentsView Loads the PostgreSQL DSN

Configuration Loading in internal/config/config.go

The configuration loading flow begins in internal/config/config.go, where the environment is inspected during initialization. According to the source code, lines 998–1000 assign the raw value of AGENTSVIEW_PG_URL directly to the configuration struct:

func (c *Config) loadEnv() {
    // …other env vars…
    if v := os.Getenv("AGENTSVIEW_PG_URL"); v != "" {
        c.PG.URL = v          // stored exactly as provided
    }
    // …
}

Notice that os.Getenv retrieves the string as-is, with no transformation or expansion logic applied.

Connection Initialization in internal/postgres/connect.go

When the server starts, the postgres.Open function in internal/postgres/connect.go (lines 45–47) receives the DSN string directly from c.PG.URL. The implementation passes this string unchanged to the underlying driver:

func Open(dsn, schema string, allowInsecure bool) (*sql.DB, error) {
    // dsn is the raw string from AGENTSVIEW_PG_URL
    // No environment expansion here – the DSN is used as‑is.
    connStr, err := appendConnParams(dsn, map[string]string{
        "search_path": quoted,
        "TimeZone":    "UTC",
    })
    // pgx driver parses connStr internally.
    db, err := sql.Open("pgx", connStr)
    // …
}

The appendConnParams helper only appends runtime parameters such as search_path and TimeZone; it does not scan for or expand environment variable references.

Why Environment Variables Are Not Expanded Automatically

The AgentsView codebase deliberately avoids automatic expansion to prevent side effects and maintain predictable configuration behavior. Specifically:

  • No os.ExpandEnv calls: Neither internal/config/config.go nor internal/postgres/connect.go invokes os.ExpandEnv or equivalent helpers on the DSN string.
  • Direct pgx handoff: The DSN is passed directly to pgconn.ParseConfig within the pgx driver, which expects a fully-formed connection string.
  • Verbatim preservation: Any ${VAR} or $VAR placeholders remain literal characters in the connection string, likely causing authentication failures if unexpanded.

This design choice means that if you set AGENTSVIEW_PG_URL to postgres://user:${PG_PASS}@host/db, the application attempts to connect using the literal username user:${PG_PASS}@host rather than substituting the value of the PG_PASS environment variable.

Implementing Manual Environment Variable Expansion

To use dynamic values in your PostgreSQL DSN, you must expand the environment variables before setting AGENTSVIEW_PG_URL. This pre-processing can occur in your shell wrapper, init script, or a Go program that prepares the environment.

Here is a standalone example that demonstrates the expansion pattern:

package main

import (
    "os"
    "log"
)

func main() {
    // Assume PG_PASS holds the password.
    raw := os.Getenv("AGENTSVIEW_PG_URL") // "postgres://user:${PG_PASS}@host/db"
    dsn := os.ExpandEnv(raw)              // expands ${PG_PASS}
    if err := os.Setenv("AGENTSVIEW_PG_URL", dsn); err != nil {
        log.Fatalf("cannot set expanded DSN: %v", err)
    }

    // Proceed to start AgentsView (e.g. exec.Command or import the server package)
}

Alternatively, in a bash deployment script:

export AGENTSVIEW_PG_URL="postgres://user:${PG_PASS}@localhost:5432/agentsview"
./agentsview-server

In this approach, the shell performs the expansion before the process starts, ensuring AgentsView receives the fully materialized connection string.

Summary

  • AgentsView reads the PostgreSQL DSN exclusively from the AGENTSVIEW_PG_URL environment variable.
  • The configuration loader in internal/config/config.go stores the value verbatim without calling os.ExpandEnv.
  • The connection opener in internal/postgres/connect.go passes the raw DSN directly to the pgx driver.
  • To embed dynamic credentials or hostnames, expand environment variables before exporting AGENTSVIEW_PG_URL, either via shell substitution or programmatically using os.ExpandEnv.

Frequently Asked Questions

Does AgentsView support ${VAR} syntax in AGENTSVIEW_PG_URL?

No. AgentsView does not parse or expand ${VAR} or $VAR syntax within the AGENTSVIEW_PG_URL value. The string is read literally from the environment and passed directly to the PostgreSQL driver. Any variable references must be resolved by your shell or a pre-processing script before the application starts.

How can I securely inject passwords into the PostgreSQL DSN?

You should expand the password variable in your deployment environment before setting AGENTSVIEW_PG_URL. For example, use shell expansion (export AGENTSVIEW_PG_URL="postgres://user:${PG_PASS}@host/db") or a secrets management tool that injects fully-formed connection strings. Avoid committing DSNs with placeholder syntax to version control.

Where does the DSN parsing happen in the codebase?

The DSN is initially captured in internal/config/config.go (lines 998–1000) and subsequently processed in internal/postgres/connect.go (lines 45–47). However, "parsing" in the context of connection parameters occurs inside the pgx driver via pgconn.ParseConfig, which AgentsView invokes indirectly through sql.Open("pgx", connStr).

Can I use multiple environment variables in the DSN string?

You can include multiple variable references (e.g., postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/db), but AgentsView will not expand them. You must ensure all variables are substituted by your shell or a wrapper script before the application reads AGENTSVIEW_PG_URL. The final value exported to the environment must contain the actual credentials and hostnames, not placeholder syntax.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →