Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf1591cdaa | |||
| d4154cfec6 | |||
| 6e411160a6 | |||
| e25d112787 | |||
| 3b5f3423c8 | |||
| 084c8fdfb3 |
+6
-2
@@ -5,8 +5,12 @@
|
|||||||
config/
|
config/
|
||||||
backups/
|
backups/
|
||||||
|
|
||||||
# Legacy .env / proxy.env (no longer used — config is in ./config/). Still
|
# .env: NOT app config (that's ./config/, generated by setup.sh) — this is
|
||||||
# ignored in case a migrated deployment hasn't deleted them yet.
|
# docker compose's own auto-loaded env file, which setup.sh uses only to
|
||||||
|
# persist *_GIT_COMMIT build args so an ad-hoc rebuild of a single service
|
||||||
|
# still bakes the right commit hash. Generated; never commit.
|
||||||
|
# proxy.env: legacy, no longer used — still ignored in case an old
|
||||||
|
# deployment hasn't deleted it yet.
|
||||||
.env
|
.env
|
||||||
proxy.env
|
proxy.env
|
||||||
|
|
||||||
|
|||||||
@@ -8,3 +8,6 @@
|
|||||||
path = jump-host
|
path = jump-host
|
||||||
url = https://github.com/theta42/jump-host.git
|
url = https://github.com/theta42/jump-host.git
|
||||||
branch = master
|
branch = master
|
||||||
|
[submodule "ldap-client"]
|
||||||
|
path = ldap-client
|
||||||
|
url = https://github.com/theta42/ldap-client.git
|
||||||
|
|||||||
@@ -10,6 +10,95 @@ for what changed inside the apps it composes.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.20.0] - 2026-07-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **`setup.sh` persists `SSO_GIT_COMMIT`/`PROXY_GIT_COMMIT`/`JUMP_GIT_COMMIT` into `./.env`** (new `env_upsert` helper), which `docker compose` auto-loads on every future invocation in this directory. Previously these were only `export`ed for the current shell, so an ad-hoc `docker compose up --build <service>` run later (outside a full `setup.sh` run) would build with an empty `GIT_COMMIT` arg — and since each submodule's checked-out `.git` is a pointer file, not a real repo, the in-container git fallback can't resolve it either, so the image silently baked "unknown" as its commit hash. `.gitignore`'s `.env` comment updated to describe this (it was previously labeled "legacy, no longer used").
|
||||||
|
|
||||||
|
### Submodules bumped
|
||||||
|
- jump-host `v1.10.2` -> [`v1.11.0`](https://github.com/theta42/jump-host/releases/tag/v1.11.0)
|
||||||
|
- ldap-client `v1.0.0` -> [`v1.1.0`](https://github.com/theta42/ldap-client/releases/tag/v1.1.0)
|
||||||
|
- proxy `v1.8.0` -> [`v1.9.0`](https://github.com/theta42/proxy/releases/tag/v1.9.0)
|
||||||
|
- sso-manager-node `v1.9.0` -> [`v1.10.0`](https://github.com/theta42/sso-manager-node/releases/tag/v1.10.0)
|
||||||
|
|
||||||
|
#### sso-manager-node — [v1.10.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.10.0)
|
||||||
|
|
||||||
|
##### Added
|
||||||
|
- `app_super_admin` cross-app group: members are full admins here regardless of `app_sso_admin` membership. The same group is now also recognized by proxy and jump-host, and by `ldap-client`'s SSSD access filter (SSH login on every host).
|
||||||
|
|
||||||
|
##### Changed
|
||||||
|
- Renamed the Executive page to Overview (route, view, `/api/metrics/overview`, nav label, docs). `/executive` kept as a 301 redirect.
|
||||||
|
|
||||||
|
#### proxy — [v1.9.0](https://github.com/theta42/proxy/releases/tag/v1.9.0)
|
||||||
|
|
||||||
|
##### Added
|
||||||
|
- `app_super_admin` cross-app group recognized as a global admin (`conf.auth.adminGroups`).
|
||||||
|
|
||||||
|
##### Changed
|
||||||
|
- Users and Permissions pages: the always-visible sidebar "Add" forms are now an "Add User"/"Add Permission" button that opens an `app.modal` dialog, matching the hosts.ejs convention.
|
||||||
|
- Let's Encrypt ACME account key now defaults to the already-persisted `/data` volume instead of a CWD-relative path (`./le_key.cert` -> `/app/le_key.cert` in the container), which was lost on every image rebuild.
|
||||||
|
|
||||||
|
#### jump-host — [v1.11.0](https://github.com/theta42/jump-host/releases/tag/v1.11.0)
|
||||||
|
|
||||||
|
##### Added
|
||||||
|
- `app_super_admin` (cross-app) and `app_jump_admin` groups: super admins are full admins here same as `app_sso_admin`; jump admins get audit page/data access without other admin rights. The Audit page/API is now actually admin-gated server-side (previously the page shell rendered for any logged-in user, only its data was gated).
|
||||||
|
- Host list adds Last connection/Last failed connection columns and highlights rows green (a session is live right now) or yellow (the most recent attempt failed), backed by new per-host last-success/last-fail timestamps.
|
||||||
|
|
||||||
|
##### Changed
|
||||||
|
- Dashboard's stat boxes and Top hosts/Top users cards moved to the Audit page. "All hosts" renamed to "My hosts".
|
||||||
|
|
||||||
|
#### ldap-client — [v1.1.0](https://github.com/theta42/ldap-client/releases/tag/v1.1.0)
|
||||||
|
|
||||||
|
##### Added
|
||||||
|
- `app_super_admin` cross-app group now grants SSH login access to every host (`ldap_access_filter` + `ldap_access_groups`), matching the same group's admin rights in sso-manager-node, proxy, and jump-host. Sudo is not yet extended to super admins (`ldap_sudo_search_filter` remains non-functional on this SSSD version — pre-existing, documented gap).
|
||||||
|
|
||||||
|
## [1.19.0] - 2026-07-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **New `ldap-client` submodule + `ldap-test-host` service** (`jump-host` compose profile): a real SSSD + AuthorizedKeysCommand LDAP-joined downstream host for testing jump-host's actual key-injection -> upstream-connect flow end-to-end against this stack's own local LDAP, instead of a container with a manually-dropped public key in `authorized_keys`. Verified live (SSH CLI and WinSCP) through jump-host's `uid_-_target` grammar.
|
||||||
|
|
||||||
|
#### ldap-client — [v1.0.0](https://github.com/theta42/ldap-client/releases/tag/v1.0.0) (first tagged release)
|
||||||
|
|
||||||
|
##### Added
|
||||||
|
- Docker test fixture (`Dockerfile` + `entrypoint.sh`): Ubuntu 22.04 + sssd + sshd, no systemd required.
|
||||||
|
|
||||||
|
##### Fixed
|
||||||
|
Building that fixture surfaced three real bugs that would break login on any deployment, not just the test fixture:
|
||||||
|
- `sssd.conf.mo` used `ldap_bind_dn`/`ldap_bind_pw`, which aren't real SSSD options — corrected to `ldap_default_bind_dn` / `ldap_default_authtok(_type)`.
|
||||||
|
- `sssd.conf.mo` had no explicit `services =` list, so SSSD started only its backend, never the nss/pam responders — `getent passwd <ldap-user>` silently failed even with the domain reachable.
|
||||||
|
- `ldap-ssh-key.sh`'s `memberof` filter was missing the `cn=` prefix on the group name, so the AuthorizedKeysCommand script always returned zero keys for a correctly-provisioned user — no error, just silently nothing.
|
||||||
|
|
||||||
|
#### sso-manager-node — [v1.9.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.9.0)
|
||||||
|
|
||||||
|
##### Added
|
||||||
|
- Directory modal's Associated LDAP Groups tab now supports full membership management: view, add, and remove members/owners of each associated group directly from the tab.
|
||||||
|
- `app.util.revealItem()` (shared `app-base.js`): scrolls a just-added/-edited element into view and flashes its background.
|
||||||
|
|
||||||
|
##### Changed
|
||||||
|
- Groups page's search/sort bar is now sticky while scrolling.
|
||||||
|
- Directory table: Kind/Name/Env/Host merged into a single "Resource" column.
|
||||||
|
|
||||||
|
#### proxy — [v1.8.0](https://github.com/theta42/proxy/releases/tag/v1.8.0)
|
||||||
|
|
||||||
|
##### Added
|
||||||
|
- Users backed by SSO/OIDC login are now marked "External (SSO)" and read-only (password-change hidden client-side, `PUT /password/:username` rejects with 403 server-side). Redis user-backend only.
|
||||||
|
|
||||||
|
##### Changed
|
||||||
|
- All pages now wrap their content in a standard-width container, matching sso-manager-node instead of rendering full-bleed.
|
||||||
|
- Users and Permissions pages converted from bare `<table>`s to the card-grid convention already used on the Groups page.
|
||||||
|
|
||||||
|
#### jump-host — [v1.10.2](https://github.com/theta42/jump-host/releases/tag/v1.10.2)
|
||||||
|
|
||||||
|
##### Changed
|
||||||
|
- Dashboard, Sessions, and Audit pages now match sso-manager-node/proxy's page width.
|
||||||
|
- Audit's nav entry is now admin-gated (`groups: ['admin']`).
|
||||||
|
|
||||||
|
### Bumped
|
||||||
|
- sso-manager-node -> [v1.9.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.9.0)
|
||||||
|
- proxy -> [v1.8.0](https://github.com/theta42/proxy/releases/tag/v1.8.0)
|
||||||
|
- jump-host -> [v1.10.2](https://github.com/theta42/jump-host/releases/tag/v1.10.2)
|
||||||
|
- ldap-client -> [v1.0.0](https://github.com/theta42/ldap-client/releases/tag/v1.0.0) (new submodule)
|
||||||
|
|
||||||
## [1.18.0] - 2026-07-28
|
## [1.18.0] - 2026-07-28
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# ldap-client config for the optional local jump-host test fixture
|
||||||
|
# (ldap-test-host service in docker-compose.yml, jump-host compose profile).
|
||||||
|
# Copy to ./config/ldap-test-host.vars and fill in the bind password from
|
||||||
|
# your own ./config/sso-secrets.js's `serviceAccountPass` (the
|
||||||
|
# cn=ldapclient,ou=people,<base> service account bootstrap/bootstrap.js
|
||||||
|
# creates specifically for this kind of 3rd-party/container LDAP bind).
|
||||||
|
#
|
||||||
|
# This is what lets ldap-test-host be a REAL SSSD+AuthorizedKeysCommand-joined
|
||||||
|
# downstream host, so jump-host's key-injection -> upstream-connect flow can
|
||||||
|
# be exercised end-to-end against something more than a container with a
|
||||||
|
# manually-dropped public key in authorized_keys.
|
||||||
|
export ldap_host="sso-manager"
|
||||||
|
export ldap_base_dn="dc=localtest,dc=me"
|
||||||
|
|
||||||
|
export ldap_bind_dn="cn=ldapclient,ou=People,$ldap_base_dn"
|
||||||
|
export ldap_bind_password="REPLACE_WITH_serviceAccountPass_FROM_sso-secrets.js"
|
||||||
|
|
||||||
|
# sso_url/sso_token deliberately left unset -- register the host + access
|
||||||
|
# group manually via the Directory admin API instead (index.sh's optional
|
||||||
|
# auto-registration also wants a parent site Resource to exist first).
|
||||||
|
# index.sh gates that block on `[[ -v sso_token ]]`, which is true even for
|
||||||
|
# an empty string, so leave these genuinely absent, not "".
|
||||||
|
|
||||||
|
export ldap_location="jumptest"
|
||||||
|
|
||||||
|
ldap_access_groups=( "${ldap_location}_access" "${ldap_location}_host_$(hostname)_access" )
|
||||||
@@ -189,6 +189,31 @@ services:
|
|||||||
- jump-data:/var/lib/jump-host # generated host keys persist here
|
- jump-data:/var/lib/jump-host # generated host keys persist here
|
||||||
- jump-redis-data:/data # Redis (sessions, OAuth state, API tokens) persists here
|
- jump-redis-data:/data # Redis (sessions, OAuth state, API tokens) persists here
|
||||||
|
|
||||||
|
# A real, LDAP-joined (SSSD + AuthorizedKeysCommand) downstream host for
|
||||||
|
# testing jump-host's actual key-injection -> upstream-connect flow --
|
||||||
|
# a container with a manually-dropped public key in authorized_keys never
|
||||||
|
# exercises the LDAP-key-serving path a real production host does. Built
|
||||||
|
# from the theta42/ldap-client submodule -- see ./config/ldap-test-host.vars
|
||||||
|
# for setup notes. Same jump-host profile, so
|
||||||
|
# `docker compose --profile jump-host up` brings up jump-host and a host it
|
||||||
|
# can actually reach together.
|
||||||
|
ldap-test-host:
|
||||||
|
profiles: ["jump-host"]
|
||||||
|
build:
|
||||||
|
context: ./ldap-client
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: ldap-test-host
|
||||||
|
hostname: ldap-test-host
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [theta-net]
|
||||||
|
depends_on:
|
||||||
|
sso-manager:
|
||||||
|
condition: service_healthy
|
||||||
|
privileged: false
|
||||||
|
volumes:
|
||||||
|
- ./config/ldap-test-host.vars:/config/ldap.vars:ro
|
||||||
|
- ./config/ldap-ca.crt:/config/ldap-ca.crt:ro
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
theta-net:
|
theta-net:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|||||||
+1
-1
Submodule jump-host updated: 6771904932...82318da484
Submodule
+1
Submodule ldap-client added at dd9f2fbd9c
+1
-1
Submodule proxy updated: 3f2ef57c78...8c0eaf0d07
@@ -88,6 +88,23 @@ rand_hex() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Upsert KEY=VALUE into ./.env, which `docker compose` auto-loads for every
|
||||||
|
# future invocation in this directory. Used to persist the *_GIT_COMMIT build
|
||||||
|
# args (see SSO_GIT_COMMIT/PROXY_GIT_COMMIT/JUMP_GIT_COMMIT below) so that an
|
||||||
|
# ad-hoc `docker compose up --build <service>` run later, OUTSIDE this script,
|
||||||
|
# still resolves the right commit instead of silently baking "unknown" (the
|
||||||
|
# submodule .git pointer file can't be resolved from inside the build
|
||||||
|
# context, so the value must come from the host via this file or the export).
|
||||||
|
env_upsert() {
|
||||||
|
local key="$1" val="$2" file=./.env
|
||||||
|
touch "$file"
|
||||||
|
if grep -q "^${key}=" "$file" 2>/dev/null; then
|
||||||
|
sed -i "s|^${key}=.*|${key}=${val}|" "$file"
|
||||||
|
else
|
||||||
|
printf '%s=%s\n' "$key" "$val" >> "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Detect docker compose (v2 plugin `docker compose` or v1 standalone `docker-compose`).
|
# Detect docker compose (v2 plugin `docker compose` or v1 standalone `docker-compose`).
|
||||||
if docker compose version >/dev/null 2>&1; then
|
if docker compose version >/dev/null 2>&1; then
|
||||||
COMPOSE=(docker compose)
|
COMPOSE=(docker compose)
|
||||||
@@ -637,6 +654,7 @@ backup_before_rebuild
|
|||||||
# docker-compose.yml and sso-manager-node's Dockerfile.openldap.
|
# docker-compose.yml and sso-manager-node's Dockerfile.openldap.
|
||||||
SSO_GIT_COMMIT="$(git -C sso-manager-node rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
SSO_GIT_COMMIT="$(git -C sso-manager-node rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||||
export SSO_GIT_COMMIT
|
export SSO_GIT_COMMIT
|
||||||
|
env_upsert SSO_GIT_COMMIT "$SSO_GIT_COMMIT"
|
||||||
info "Building + starting sso-manager (first run builds the image; this takes a while)..."
|
info "Building + starting sso-manager (first run builds the image; this takes a while)..."
|
||||||
"${COMPOSE[@]}" up -d --build sso-manager
|
"${COMPOSE[@]}" up -d --build sso-manager
|
||||||
|
|
||||||
@@ -722,6 +740,7 @@ fi
|
|||||||
# PROXY_GIT_COMMIT: same reasoning as SSO_GIT_COMMIT above.
|
# PROXY_GIT_COMMIT: same reasoning as SSO_GIT_COMMIT above.
|
||||||
PROXY_GIT_COMMIT="$(git -C proxy rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
PROXY_GIT_COMMIT="$(git -C proxy rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||||
export PROXY_GIT_COMMIT
|
export PROXY_GIT_COMMIT
|
||||||
|
env_upsert PROXY_GIT_COMMIT "$PROXY_GIT_COMMIT"
|
||||||
info "Building + starting proxy (first run builds the image; this takes a while)..."
|
info "Building + starting proxy (first run builds the image; this takes a while)..."
|
||||||
"${COMPOSE[@]}" up -d --build proxy
|
"${COMPOSE[@]}" up -d --build proxy
|
||||||
|
|
||||||
@@ -788,6 +807,7 @@ if [[ "$JUMP_ENABLED" == "1" ]]; then
|
|||||||
JUMP_HOST="${CFG_JUMP_HOST:-jump.${SSO_HOST#sso.}}"
|
JUMP_HOST="${CFG_JUMP_HOST:-jump.${SSO_HOST#sso.}}"
|
||||||
JUMP_GIT_COMMIT="$(git -C jump-host rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
JUMP_GIT_COMMIT="$(git -C jump-host rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||||
export JUMP_GIT_COMMIT
|
export JUMP_GIT_COMMIT
|
||||||
|
env_upsert JUMP_GIT_COMMIT "$JUMP_GIT_COMMIT"
|
||||||
info "Building + starting jump-host (optional; enabled via CFG_JUMP_HOST_ENABLED)..."
|
info "Building + starting jump-host (optional; enabled via CFG_JUMP_HOST_ENABLED)..."
|
||||||
"${COMPOSE[@]}" up -d --build jump-host
|
"${COMPOSE[@]}" up -d --build jump-host
|
||||||
|
|
||||||
|
|||||||
+1
-1
Submodule sso-manager-node updated: 724f5d8496...aa2592ea4e
Reference in New Issue
Block a user