Configuration
Interactive setup
Section titled “Interactive setup”-
Start the login wizard:
Terminal window redmine auth login -
Provide your Redmine server URL and authentication method (API key or username/password).
-
Optionally set a default project — it is prepopulated in project-scoped commands.
-
The wizard writes a profile to
~/.redmine-cli.yaml. You are ready to go.
Multiple profiles
Section titled “Multiple profiles”You can authenticate against as many Redmine instances as you like. Each redmine auth login creates a named profile.
redmine auth login # second instanceredmine auth login --name work # with an explicit nameredmine auth list # see all profilesredmine auth switch # interactive pickerredmine --profile work issues listredmine auth statusConfig file
Section titled “Config file”Directory~/
- .redmine-cli.yaml active profile + all profile data
Directory.local/bin/
- redmine binary (install script target)
active_profile: workprofiles: work: server: https://redmine.work.com auth_method: apikey api_key: your-api-key default_project: myproject output_format: table personal: server: https://redmine.personal.com auth_method: apikey api_key: another-key output_format: jsonThe CLI writes the config file atomically with mode 0600: a new file is written next to it and renamed into place, so an interrupted write never leaves a truncated config. A missing config directory is created with mode 0700. If the config path is a symlink (for example into a dotfiles checkout), the file it points to is updated and the link is kept. A config file you made read-only is never overwritten. A file that cannot be replaced by a rename (for example a config bind-mounted into a container, or one in a directory you cannot write to) is overwritten in place instead.
System keyring (optional)
Section titled “System keyring (optional)”You can keep the API key (or password) out of the config file and in your operating system keyring instead. It is fully opt-in and backward compatible: existing plaintext profiles keep working unchanged.
-
Opt in during login. The wizard asks whether to use the keyring when a usable backend is detected on a TTY. For scripted logins use the flag:
Terminal window redmine auth login --keyring -
The profile records
credential_store: keyringand the secret is written to the keyring, not the file. On the next run the secret is read back from the keyring automatically.
Logging in again for a profile that already uses the keyring keeps the keyring by default; it never silently falls back to the plaintext file. Pass --keyring=false to explicitly switch a profile back to plaintext storage.
The MCP server’s bearer token (mcp.auth_token, see AI agents) is kept in the keyring too. A keyring profile that still has a plaintext mcp.auth_token keeps working: the value in the file is used, and it is moved into the keyring and removed from the file the next time the CLI saves the config (for example on redmine auth login or redmine auth switch). If the keyring is unavailable at that point, the token stays in the file and the save still succeeds. To rotate the token, write the new value into mcp.auth_token; REDMINE_MCP_AUTH_TOKEN and --auth-token still take precedence. Switching the profile back to plaintext moves the token back into the file, and redmine auth logout removes it from the keyring.
Resolution order is CLI flag, then environment variable, then keyring, then the plaintext file field. Environment variables and flags are resolved before the keyring is consulted, so an explicit API key or password means that secret is not read from the keyring.
The MCP token is a separate lookup: on a keyring profile, redmine mcp serve --http reads it from the keyring whenever --auth-token-file, --auth-token, REDMINE_MCP_AUTH_TOKEN and mcp.auth_token all leave it unset, even if the API key came from a flag or environment variable. If that read fails (for example a locked keychain over SSH), or REDMINE_NO_KEYRING=1 disables it, the server refuses to start rather than serve without a token that may exist.
Environment variables
Section titled “Environment variables”Every setting can be overridden with a REDMINE_-prefixed variable:
export REDMINE_SERVER=https://redmine.example.comexport REDMINE_API_KEY=your-api-keyexport REDMINE_AUTH_METHOD=apikey
# opt out of the startup update checkexport REDMINE_NO_UPDATE_CHECK=1
# refuse all requests that modify data (read-only mode)export REDMINE_READ_ONLY=1
# hard-disable the optional system keyringexport REDMINE_NO_KEYRING=1
# wait at most 5 minutes for the server to start responding (default 0: no limit)export REDMINE_HTTP_TIMEOUT=5m# hide the environment from --jq expressions (env / $ENV evaluate to {})export REDMINE_JQ_NO_ENV=1See Self-Update for details on the update check.
Global flags
Section titled “Global flags”Flags take precedence over config values and environment variables.
| Flag | Description |
|---|---|
-s, --server |
Redmine server URL |
-k, --api-key |
API key for authentication (visible in process listings; see below) |
--api-key-file |
Read the API key from a file, or from stdin with - |
--profile |
Use a specific auth profile |
--config |
Config file path (default ~/.redmine-cli.yaml) |
-o, --output |
Output format: table, json (see Output formats) |
-q, --jq |
Filter JSON output with a jq expression; implies -o json (see Filtering with –jq) |
--no-color |
Disable colored output |
--read-only |
Refuse all requests that modify data on the server |
--header |
Extra HTTP header as "Name: value" (repeatable) |
-v, --verbose |
Enable debug logging |
Passing an API key
Section titled “Passing an API key”A key given with --api-key shows up in process listings (ps), shell history, and CI logs. Prefer one of these instead:
redmine --api-key-file ~/.config/redmine/key issues list # read from a filepass show redmine | redmine --api-key-file - issues list # read from stdinexport REDMINE_API_KEY=your-api-key # environment variableredmine auth login --keyring # system keyring--api-key-file trims surrounding whitespace, including the trailing newline, and cannot be combined with --api-key. With -, stdin is consumed by the key, so it cannot also feed a command that reads stdin.
Server overrides and stored credentials
Section titled “Server overrides and stored credentials”A profile’s stored secret (in the config file or the system keyring) belongs to the server the profile was saved with. If --server or REDMINE_SERVER points the profile at a different origin (scheme, host, or port), the CLI still sends that secret, but prints a warning first:
warning: sending the stored credentials of profile "work" (for https://redmine.work.com) to https://other.example.com; pass --api-key-file or REDMINE_API_KEY explicitly to silence thisSupply the key for the other server explicitly (--api-key-file, REDMINE_API_KEY, or REDMINE_PASSWORD for basic auth) to silence the warning.
A profile’s custom headers can carry tokens for the same server, so they get the same check. The warning names the headers, never their values:
warning: sending the configured headers of profile "work" (for https://redmine.work.com) to https://other.example.com: X-Proxy-Token; pass the headers meant for that server with --header to silence thisA header given with --header on the same command is not checked, since it replaces the profile header of that name.
Read-only mode
Section titled “Read-only mode”Point the CLI at a production Redmine without any risk of changing data. When enabled, every request that would modify the server is refused before it is sent; all listing, viewing, and searching commands keep working.
Enable it in any of three ways (precedence: flag > environment variable > config):
redmine --read-only issues list # single invocationexport REDMINE_READ_ONLY=1 # whole shell sessionprofiles: prod: server: https://redmine.example.com auth_method: apikey api_key: your-api-key read_only: truePass --read-only=false to override the environment variable or a read_only: true profile for a single invocation.
Custom HTTP headers
Section titled “Custom HTTP headers”Some servers sit behind a firewall or reverse proxy that expects extra request headers, for example a browser-like User-Agent or an access token. Add them per profile under headers:
profiles: work: server: https://redmine.work.com auth_method: apikey api_key: your-api-key headers: User-Agent: Mozilla/5.0 X-Proxy-Token: your-proxy-tokenFor a single invocation, pass --header (repeatable). It overrides a profile header with the same name:
redmine --header "User-Agent: Mozilla/5.0" issues listPassed to redmine auth login, the headers are used for the connection test and saved to the profile, so a server that requires them works from the first login:
redmine auth login --header "User-Agent: Mozilla/5.0"Logging in again keeps a profile’s headers as long as the server’s host stays the same. If you point the profile at a different server, its headers are dropped, since they may be secrets meant for the old one. To remove a header, delete it from the config file.
Headers are only sent to the configured server, never to hosts it redirects to. Authentication headers always take precedence. Headers the HTTP client manages itself (Host, Content-Type, Content-Length, Transfer-Encoding, Connection, Accept-Encoding) cannot be configured, and empty values are rejected. Without a configured User-Agent, the CLI identifies itself as redmine-cli/<version>.
Connection security
Section titled “Connection security”Use an https:// server URL where you can. Plain http:// is supported, for example for an internal instance, but the API key or password then crosses the network unencrypted. redmine auth login points this out once when you enter a plain http:// URL for a host other than loopback (localhost and names under it such as dev.localhost, 127.0.0.0/8, ::1); other commands connect without a warning.
Redirects are followed up to 10 hops. A redirect from https:// to http:// is always refused, so a connection that starts encrypted is never downgraded. Credentials and custom headers are only sent when both the scheme and the host (including the port) match the configured server; the one exception is an http:// server redirecting to https:// on the same host. A redirect away from the configured server is refused when it leads to a loopback, private or otherwise non-public address, for API requests (including redmine api) and attachment downloads alike; see attachments download for the full rules.
Timeouts and limits
Section titled “Timeouts and limits”Connecting to the server times out after 30 seconds and the TLS handshake after 15 seconds. By default there is no limit on how long the server may take to start responding, so slow queries on a busy Redmine still complete, and no limit on total request time, so large attachment downloads keep streaming as long as data arrives. To give up on a server that stops answering, set REDMINE_HTTP_TIMEOUT to a Go duration such as 90s or 5m; it bounds the wait for the response to start (0, the default, means no limit).
API responses are capped at 256 MiB, and at most 1 MiB of an error response is read. Attachment downloads are not size-limited, since they are streamed to disk.
Inspect current config
Section titled “Inspect current config”redmine configPrints the active profile, server, auth method, default project, output format, read-only state, and the names of configured headers (values are hidden).