Files
jump-host/secrets.js.example
T
wmantly 36e9d5b0b3 feat: initial jump-host — SSH jump host for the theta42 stack
An SSH jump host that authenticates users against the shared LDAP
directory, authorizes them from the SSO Manager's inventory graph, and
bridges them to downstream hosts — auditing everything.

- Username-grammar routing (uid_-_target@jump) + interactive TUI picker
- Inbound LDAP auth (publickey / password with off|local|all policy)
- Directory-driven access (LDAP groups x /api/discovery/resources?group=)
- Per-user key injection into sshPublicKey, connects downstream as the user
- Shell / exec / SFTP-subsystem bridging (WinSCP works)
- Web UI + HTTP API (:3002) for audit + metrics; LDAP-admin gated
- Packaged like proxy: ops/install.sh + systemd, all-in-one Docker, compose
- Tests: 23 unit + 3 integration (node --test), all green

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 15:48:49 -04:00

70 lines
2.3 KiB
Plaintext

'use strict';
//
// jump-host secrets. Copy to your secrets file and fill in.
// Bare metal: /etc/jump-host/secrets.js (install.sh seeds this)
// Docker: mount at /config/jump-secrets.js (the entrypoint points
// CONF_SECRETS at it); or pass the same values as app_* env.
//
// Read by @simpleworkjs/conf via CONF_SECRETS. Precedence (later wins):
// conf/base.js < conf/<NODE_ENV>.js < this file < app_* env vars.
//
module.exports = {
name: 'My Org',
// The directory the users live in (the SSO Manager's OpenLDAP).
//
// IMPORTANT: bindDN needs, beyond read on ou=people + ou=groups, WRITE on
// the sshPublicKey attribute of user entries — the jump host injects its
// own public key into each user's sshPublicKey on first use so it can
// connect downstream AS that user. Grant it with an OpenLDAP ACL, e.g.:
//
// access to attrs=sshPublicKey
// by dn.exact="cn=jumphost,ou=people,dc=example,dc=com" write
// by self write
// by * read
//
// (In the theta-env bundle this ACL is added by the bootstrap for the
// shared cn=ldapclient service account.)
ldap: {
url: 'ldaps://sso.example.com:636',
bindDN: 'cn=ldapclient,ou=people,dc=example,dc=com',
bindPassword: 'CHANGE-ME',
userBase: 'ou=people,dc=example,dc=com',
groupBase: 'ou=groups,dc=example,dc=com',
tlsOptions: { rejectUnauthorized: false },
},
// SSO Manager directory (inventory) API. apiToken is a personal access
// token (sso_<id>_<secret>) of any user that can read /api/discovery/*.
sso: {
url: 'https://sso.example.com',
apiToken: 'sso_CHANGE_ME',
},
ssh: {
listenPort: 2222,
hostKeyPath: '/var/lib/jump-host/keys',
banner: 'Theta42 Jump Host — authorized use only.\n',
// 'off' = keys only (recommended for a public host); 'local' = passwords
// only from loopback/RFC1918 clients, keys-only from the internet;
// 'all' = passwords from anywhere.
passwordAuth: 'off',
allowRawIPs: false,
connectTimeoutMs: 10000,
idleTimeoutMs: 0,
maxSessions: 100,
// Comment on the injected key; also excludes that key from inbound auth.
keyComment: 'jump-host@my-org',
},
web: { port: 3002 },
// LDAP groups whose members may use the web UI/API.
auth: { adminGroups: ['app_sso_admin'] },
redis: {
prefix: 'jump_host_',
redisConf: { url: 'redis://127.0.0.1:6379' },
},
};