Compare commits

...

4 Commits

Author SHA1 Message Date
wmantly 49bf0fa1d3 chore: release v1.15.0 2026-08-02 00:16:18 -04:00
wmantly 1b4764e328 feat: Rename SSO Manager to Jump in UI 2026-08-02 00:16:18 -04:00
wmantly db3333e26d v1.14.1: bump @simpleworkjs/bao-conf to 1.0.1
bao-conf 1.0.0's init() threw when VAULT_TOKEN was unset, crashing boot
(.catch -> process.exit(1)) in any deployment without an OpenBao sidecar
(standalone Docker, bare metal). 1.0.1 makes init() fail-soft on a
missing token (warn + continue from CONF_SECRETS). The theta-env stack
is unaffected (it always sets a scoped VAULT_TOKEN).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-01 12:47:51 -04:00
wmantly 1092031a9f v1.14.0: load secrets from OpenBao at boot via @simpleworkjs/bao-conf
bin/www now runs bao-conf.init({ path: 'jump-host' }) before
require('../models'), so the OIDC clientSecret captured at require time
inside createOidcClient sees the OpenBao-merged config. Authenticates to
OpenBao with a scoped VAULT_TOKEN (policy jump-host), never the root
token; fail-soft to CONF_SECRETS if OpenBao is unreachable.
config/jump-secrets.js becomes an operator-edit seed artifact (OpenBao
authoritative). README gains a Secrets section.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-01 12:28:46 -04:00
7 changed files with 100 additions and 28 deletions
+31
View File
@@ -1,9 +1,40 @@
# v1.15.0
- feat: Rename SSO Manager to Jump in UI
# Changelog
All notable changes to this project are documented here. Format loosely
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions
correspond to git tags (`vX.Y.Z`) and `nodejs/package.json`'s `version`.
## [1.14.1] - 2026-08-01
### Fixed
- **Bumped `@simpleworkjs/bao-conf` to 1.0.1** so standalone/no-OpenBao boots
don't crash. bao-conf 1.0.0's `init()` threw when `VAULT_TOKEN` was unset,
which — combined with `bin/www`'s `.catch(() => process.exit(1))` — made the
jump host exit at boot in any deployment without an OpenBao sidecar
(standalone Docker, bare metal). 1.0.1 makes `init()` fail-soft on a missing
token (warn + continue from `CONF_SECRETS`), matching the documented
contract. The theta-env stack is unaffected (it always sets a scoped
`VAULT_TOKEN`).
## [1.14.0] - 2026-08-01
### Changed
- **Secrets now load from OpenBao at boot** via
[@simpleworkjs/bao-conf](https://simpleworkjs.github.io/bao-conf/), which
deep-merges `secret/jump-host/conf` over the file-loaded config. The jump
host authenticates to OpenBao with a scoped `VAULT_TOKEN` (policy
`jump-host` — read-only on its own path), never the root token. Because the
OIDC `clientSecret` is captured at require time inside `createOidcClient`
(during `require('../models')`), `bin/www` now runs `bao-conf.init()`
**before** `require('../models')`. Fail-soft: if OpenBao is unreachable,
boot continues from `CONF_SECRETS`. The `config/jump-secrets.js` file is now
an operator-edit seed artifact (gitignored); OpenBao is authoritative. See
theta-env's [Secrets docs](https://theta42.github.io/theta-env/secrets/).
- Bumped package version to track the release tag.
## [1.11.0] - 2026-07-30
### Added
+16
View File
@@ -159,6 +159,22 @@ Config layers via [@simpleworkjs/conf](https://www.npmjs.com/package/@simplework
`conf/base.js` < `conf/<NODE_ENV>.js` < the `CONF_SECRETS` file < `app_*` env.
See `secrets.js.example` for every key.
## Secrets
At boot, [@simpleworkjs/bao-conf](https://simpleworkjs.github.io/bao-conf/)
deep-merges `secret/jump-host/conf` from **OpenBao** over the file-loaded
config. The jump host's OIDC `clientSecret` is captured at require time
(inside `createOidcClient` during `require('../models')`), so `bin/www` runs
`bao-conf.init()` **before** `require('../models')`. Fail-soft: if OpenBao is
unreachable, boot continues from `CONF_SECRETS`. The jump host authenticates to
OpenBao with the scoped `VAULT_TOKEN` (env, policy `jump-host` — read only
`secret/jump-host/conf`), never the root token.
The `config/jump-secrets.js` file is an operator-edit seed artifact
(gitignored); the bootstrap writes the generated API token + OAuth client
into OpenBao, which is authoritative. For the full architecture see
theta-env's **[Secrets docs](https://theta42.github.io/theta-env/secrets/)**.
## Development
```
+34 -23
View File
@@ -9,32 +9,43 @@ const http = require('http');
const conf = require('@simpleworkjs/conf');
const { Server } = require('socket.io');
require('../models');
// @simpleworkjs/conf loads ./config/jump-secrets.js synchronously, then
// @simpleworkjs/bao-conf deep-merges secret/jump-host/conf from OpenBao over
// it. The OIDC clientSecret is captured at require time inside models (via
// createOidcClient), so the fetch MUST resolve before require('../models').
// Fail-soft: if OpenBao is unreachable, init() leaves conf as the file-loaded
// fallback and boot continues from ./config/jump-secrets.js.
require('@simpleworkjs/bao-conf').init({ path: 'jump-host', conf }).then(() => {
require('../models');
const app = require('../app');
const middleware = require('../middleware/auth');
const sshServer = require('../services/ssh_server');
const app = require('../app');
const middleware = require('../middleware/auth');
const sshServer = require('../services/ssh_server');
const webPort = (conf.web && conf.web.port) || 3002;
const server = http.createServer(app);
const webPort = (conf.web && conf.web.port) || 3002;
const server = http.createServer(app);
// Socket.IO — the client framework (app-base.js) opens an authenticated socket.
// We don't push anything yet, but serving /socket.io keeps the shared front-end
// working exactly as it does in the sibling apps.
const io = new Server(server);
io.use(middleware.authIO);
app.io = io;
// Socket.IO — the client framework (app-base.js) opens an authenticated socket.
// We don't push anything yet, but serving /socket.io keeps the shared front-end
// working exactly as it does in the sibling apps.
const io = new Server(server);
io.use(middleware.authIO);
app.io = io;
server.listen(webPort, () => {
console.log(`[web] jump-host UI/API on :${server.address().port}`);
});
server.listen(webPort, () => {
console.log(`[web] jump-host UI/API on :${server.address().port}`);
});
sshServer.start();
sshServer.start();
function shutdown() {
console.log('[jump-host] shutting down');
server.close();
process.exit(0);
}
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);
function shutdown() {
console.log('[jump-host] shutting down');
server.close();
process.exit(0);
}
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);
}).catch(err => {
console.error('boot failed:', err);
process.exit(1);
});
+1 -1
View File
@@ -6,7 +6,7 @@
// values (LDAP creds, SSO API token) belong in the secrets file.
module.exports = {
name: 'SSO Manager',
name: 'Jump',
logo: '/static/img/theta42.svg',
// LDAP directory the users live in (same directory the SSO manages).
+15 -2
View File
@@ -1,16 +1,17 @@
{
"name": "t42-jump-host",
"version": "1.9.0",
"version": "1.15.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "t42-jump-host",
"version": "1.9.0",
"version": "1.15.0",
"license": "MIT",
"dependencies": {
"@fortawesome/fontawesome-free": "^7.3.0",
"@simpleworkjs/app-stack": "^1.0.0",
"@simpleworkjs/bao-conf": "^1.0.0",
"@simpleworkjs/conf": "^1.2.0",
"@simpleworkjs/directory-schema": "^1.0.0",
"@simpleworkjs/frontend": "^0.2.6",
@@ -156,6 +157,18 @@
"node": ">=18.0.0"
}
},
"node_modules/@simpleworkjs/bao-conf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@simpleworkjs/bao-conf/-/bao-conf-1.0.1.tgz",
"integrity": "sha512-mcay5NQ/w9ShpIAolMP/3f9TfXSLE+d5jrA4dTPOUHDjTkdsP7pe4hMmQUmwnniR59U1bGoRIVdXjvDbX3I5nw==",
"license": "MIT",
"dependencies": {
"extend": "^3.0.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@simpleworkjs/conf": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@simpleworkjs/conf/-/conf-1.2.0.tgz",
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "t42-jump-host",
"version": "1.11.0",
"version": "1.15.0",
"description": "SSH jump host for the theta42 stack — LDAP-authenticated, directory-driven host bridging with audit and metrics",
"author": [
{
@@ -21,6 +21,7 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^7.3.0",
"@simpleworkjs/app-stack": "^1.0.0",
"@simpleworkjs/bao-conf": "^1.0.0",
"@simpleworkjs/conf": "^1.2.0",
"@simpleworkjs/directory-schema": "^1.0.0",
"@simpleworkjs/frontend": "^0.2.6",
+1 -1
View File
@@ -90,7 +90,7 @@
<hr />
<div class="d-grid">
<a href="/api/auth/oidc/start" class="btn btn-outline-primary">
<i class="fa-solid fa-id-badge"></i> Log in with SSO
<i class="fa-solid fa-id-badge"></i> Log in with Jump
</a>
</div>
<% } %>