Security practices#

What JMXPress does with credentials and data, and what you should do alongside it.

Where everything lives#

On your own server, against your own PostgreSQL database. Recordings, results, reports, diagnostics and APM credentials stay on that installation. Nothing is sent to a third party; the APM credentials you configure are used to call your provider.

APM credentials#

  • Sealed with a key held on the server, outside the database row.
  • Never sent back to a browser. A connection's page shows which secrets are set, not their values — so editing one never requires the stored credential to be sent out and back. An empty box means "unchanged".
  • Never written to logs, reports, generated test plans or test artefacts.
  • Not handed to load-generating agents, which have no need of them.

Use a read-only credential. JMXPress only reads. A token that can change your monitoring configuration is a token that does not need to be here.

Separation between teams#

Every tenant-owned table carries an organisation and is covered by a row-level security policy in PostgreSQL. The separation is enforced by the database, so a query that forgets to scope itself returns nothing rather than returning another team's data.

The application connects as a role that cannot alter tables. Schema changes run as a different, privileged role at startup — a role that could ALTER TABLE could drop the policy that constrains it.

Agents#

The agent dials out; the server never dials in. There is no listening socket on a tester's machine, no port to open, and no unauthenticated endpoint on a developer machine for the office network to find.

  • A pairing code is single-use, short-lived, one per person at a time.
  • The token is stored hashed and compared in constant time.
  • Unpairing revokes it.
  • The capture proxy an agent starts is bound to 127.0.0.1, so it is not an open forwarding proxy even on that machine.

Note Agent tokens do not rotate on a schedule. They last until somebody unpairs the machine.

Diagnostics#

The most sensitive thing JMXPress can collect, and the most locked down.

  • Off on every agent until enabled in a file on that machine.
  • Log folders must be listed explicitly; without a list, log collection is refused outright.
  • A path outside the allowed folders is refused on that machine, including one that only resolves outside after links are followed. Such files are not listed either.
  • Heap dumps of JVMs are limited to what that agent's own operating-system user can attach to.
  • Stored with restrictive permissions and removed after the retention window.

See Diagnostics.

Recording captures#

A recording stores what was sent, which for an authenticated journey includes credentials.

  • Masking is available and is off by default. That is a deliberate trade: auth headers and cookies are load-bearing, and a masked recording produces a plan that will not run until somebody supplies them again.
  • Redaction of logs and the audit trail is unconditional.

Turn masking on for a journey whose credentials should not be stored at all, and keep recordings on an installation only the team can reach.

Passwords#

Length, character classes, history depth and maximum age are set per installation in the password policy. A password may not contain the account's own address or domain.

What you should do#

  1. Put HTTPS in front of it. Certificates and a reverse proxy are a configuration change, not a code change — the agent speaks HTTPS and verifies certificates whenever the server offers it.
  2. Bind narrowly and scope the firewall rule to the subnet that needs it.
  3. Use read-only APM credentials.
  4. Leave diagnostics off except on machines where you need them, and list log folders narrowly.
  5. Back up the database, and keep the APM encryption key with it — without the key, the stored credentials cannot be read.

Reporting a problem#

Write to support@jmxpress.in. Please include enough to reproduce it, and do not put credentials in the message.