Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 84d7c96c17 | |||
| 72046a8b29 |
@@ -8,6 +8,18 @@ orchestration code; see each submodule's own `CHANGELOG.md`
|
|||||||
[sso-manager-node](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md))
|
[sso-manager-node](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md))
|
||||||
for what changed inside the apps it composes.
|
for what changed inside the apps it composes.
|
||||||
|
|
||||||
|
## [v1.38.0] - 2026-08-04
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **LDAP enrollment no longer reaches for the public domain** — `setup.sh` generated `ldap.vars` with `ldap_host` defaulting to the public SSO host (`sso.<domain>`), which the NAT/firewall blocks on the LDAP ports (389/636). It now defaults to `localhost` (the LDAP server is co-located on the stack host; `ldap_tls_reqcert=never` makes this safe), overridable with `CFG_LDAPS_HOST` for an internal hostname/IP.
|
||||||
|
- **SSH access groups match the SSO group model** (ldap-client v1.24.0) — the generated `sssd.conf` access filter and `ldap-ssh-key.sh` referenced the legacy names (`<location>_access`, `app_super_admin`); they now use `site_<location>_hosts_access` (all-hosts aggregate), `site_<location>_host_<hostname>_access`, and `god_admin`. GROUPS.md §8's example updated to match.
|
||||||
|
|
||||||
|
## [v1.37.0] - 2026-08-04
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **Group naming corrected to match docs/GROUPS.md** — per-resource groups are `{site}_{kind}_{name}_{level}` (kind always present; a host `host_theta-env` → `site_local_host_theta-env_access`, a service → `site_local_app_sso-manager_access`). The spec's §3 text was updated to state this explicitly.
|
||||||
|
- **Roll up sso v1.27.0** — group names match the docs, a site carries only god + site-wide groups, duplicate group links removed, `/api/agent/*` no longer 404s, shared-secrets POST/GET fixed, Vault Apps tab lists minted tokens, discovery promote + plugin run logs fixed. See the [sso changelog](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
## [v1.36.1] - 2026-08-04
|
## [v1.36.1] - 2026-08-04
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
+16
-16
@@ -76,17 +76,15 @@ enumerated as LDAP members, and cannot be used as Unix groups.
|
|||||||
|
|
||||||
- The **structural delimiter is `_`**. It appears only between the fixed segments
|
- The **structural delimiter is `_`**. It appears only between the fixed segments
|
||||||
of a group name.
|
of a group name.
|
||||||
- **The `S` site segment is the site resource's slug verbatim.** In the SSO
|
- **The `S` site segment is the site resource's slug verbatim** (`site_local`),
|
||||||
Directory, site/host resource slugs carry a kind prefix (`site_local`,
|
NOT re-slugified (which would corrupt the delimiter: `site_local` → `site-local`).
|
||||||
`host_theta-env`); the group builders keep them verbatim rather than
|
- **Per-resource groups are `{S}_{kind}_{name}_{level}`.** `kind` is `host` or
|
||||||
re-slugifying (which would corrupt the delimiter: `site_local` → `site-local`)
|
`app`; `name` is the resource's **name slug with the kind prefix stripped** — a
|
||||||
or inserting a separate kind segment. So a host resource `host_theta-env` under
|
host resource `host_theta-env` has name `theta-env`, so its groups are
|
||||||
site `site_local` yields `site_local_host_theta-env_access` (the `host_` is part
|
`site_local_host_theta-env_access` / `_admin`. A service (the group model's
|
||||||
of the resource slug), and the site's own admin group is `site_local_super_admin`.
|
`app`, docs §11) `sso-manager` gives `site_local_app_sso-manager_access`. The
|
||||||
Services are stored without a prefix, giving `site_local_sso-manager_access`.
|
kind segment is always present, which is what makes a resource's name
|
||||||
The kind (`host`/`app`) is used only to pick the **aggregate** the resource's
|
unambiguous even if a host and a service share a name.
|
||||||
group nests into (`{site}_hosts_*` / `{site}_apps_*`), not the resource's own
|
|
||||||
group name.
|
|
||||||
- **Within a segment, normalize to lowercase** — spaces and stray `_` → `-`; strip
|
- **Within a segment, normalize to lowercase** — spaces and stray `_` → `-`; strip
|
||||||
other non-`[a-z0-9-]`. A host named `Web 01` and a site `Main Office` (resource
|
other non-`[a-z0-9-]`. A host named `Web 01` and a site `Main Office` (resource
|
||||||
slugs `host_web-01` and `site_main-office`) yield groups `site_main-office_host_web-01_*`.
|
slugs `host_web-01` and `site_main-office`) yield groups `site_main-office_host_web-01_*`.
|
||||||
@@ -150,7 +148,9 @@ def effective(resource, level_or_cap, site):
|
|||||||
if level_or_cap in ("admin","access"):
|
if level_or_cap in ("admin","access"):
|
||||||
agg = f"{site}_{resource.kind}s_{level_or_cap}"
|
agg = f"{site}_{resource.kind}s_{level_or_cap}"
|
||||||
if user in agg: return True
|
if user in agg: return True
|
||||||
specific = f"{site}_{resource.slug}_{level_or_cap}" # slug carries its kind
|
# resource.name is the resource's name slug (kind prefix stripped); the kind
|
||||||
|
# is its own segment. A host `host_theta-env` has name `theta-env`, kind `host`.
|
||||||
|
specific = f"{site}_{resource.kind}_{resource.name}_{level_or_cap}"
|
||||||
if user in specific: return True
|
if user in specific: return True
|
||||||
if level_or_cap == "access": return effective(resource, "admin", site)
|
if level_or_cap == "access": return effective(resource, "admin", site)
|
||||||
if level_or_cap == "admin": return False # access does not imply admin
|
if level_or_cap == "admin": return False # access does not imply admin
|
||||||
@@ -232,12 +232,12 @@ Key ideas:
|
|||||||
A host should import its **own** resource groups (plus any explicitly granted
|
A host should import its **own** resource groups (plus any explicitly granted
|
||||||
ones). Because the schema is predictable, `ldap-client` can generate the per-host
|
ones). Because the schema is predictable, `ldap-client` can generate the per-host
|
||||||
`ldap_group_search_filter` from the enrolled host's identity, e.g. a host `web01`
|
`ldap_group_search_filter` from the enrolled host's identity, e.g. a host `web01`
|
||||||
at site `main-office` imports:
|
at site `main-office` (site resource slug `site_main-office`) imports:
|
||||||
|
|
||||||
```
|
```
|
||||||
(&(objectClass=groupOfNames)(|(cn=main-office_host_web01_access)
|
(&(objectClass=groupOfNames)(|(cn=site_main-office_host_web01_access)
|
||||||
(cn=main-office_host_web01_admin)
|
(cn=site_main-office_host_web01_admin)
|
||||||
(cn=main-office_host_web01_sudo)))
|
(cn=site_main-office_host_web01_sudo)))
|
||||||
```
|
```
|
||||||
|
|
||||||
So the operator (or ldap-client) selects a small allowlist of the host's `_access`
|
So the operator (or ldap-client) selects a small allowlist of the host's `_access`
|
||||||
|
|||||||
+1
-1
Submodule ldap-client updated: 31d8fa1229...ebaac181bc
@@ -1288,8 +1288,13 @@ if [[ "$CFG_THETA_AGENT_ENABLE" == "1" ]] && [[ -x /usr/local/bin/theta-agent ]]
|
|||||||
ldap_site="${CFG_SITE_NAME:-$(sso_secrets_get siteName)}"
|
ldap_site="${CFG_SITE_NAME:-$(sso_secrets_get siteName)}"
|
||||||
ldap_bind_pass="${CFG_SVC_PASS:-$(sso_secrets_get_top serviceAccountPass)}"
|
ldap_bind_pass="${CFG_SVC_PASS:-$(sso_secrets_get_top serviceAccountPass)}"
|
||||||
sso_host="${CFG_SSO_HOST:-$(sso_secrets_get ssoHost)}"
|
sso_host="${CFG_SSO_HOST:-$(sso_secrets_get ssoHost)}"
|
||||||
ldaps_host="${CFG_LDAPS_HOST:-}"
|
# The LDAP server is co-located with the stack on THIS host, so the
|
||||||
[[ -n "$ldaps_host" ]] || ldaps_host="${sso_host:-}"
|
# host must reach it over the loopback / a local address -- NEVER the
|
||||||
|
# public domain (sso.<domain>), which cannot route back to the 389/636
|
||||||
|
# ports through NAT. localhost is fine because the generated sssd.conf
|
||||||
|
# sets ldap_tls_reqcert=never (hostname verification is off). An
|
||||||
|
# operator may override with CFG_LDAPS_HOST (an internal hostname/IP).
|
||||||
|
ldaps_host="${CFG_LDAPS_HOST:-localhost}"
|
||||||
cat > ldap-client/ldap.vars <<LDAPVARS
|
cat > ldap-client/ldap.vars <<LDAPVARS
|
||||||
export ldap_host="${ldaps_host}"
|
export ldap_host="${ldaps_host}"
|
||||||
export ldap_base_dn="${ldap_base_dn}"
|
export ldap_base_dn="${ldap_base_dn}"
|
||||||
@@ -1298,7 +1303,9 @@ export ldap_bind_password="${ldap_bind_pass}"
|
|||||||
export sso_url="https://${sso_host}"
|
export sso_url="https://${sso_host}"
|
||||||
export sso_token=""
|
export sso_token=""
|
||||||
export ldap_location="${ldap_site:-local}"
|
export ldap_location="${ldap_site:-local}"
|
||||||
ldap_access_groups=( "\${ldap_location}_access" "\${ldap_location}_host_\$(hostname)_access" "god_admin" )
|
# Groups that grant SSH/access on this host (docs/GROUPS.md §8): the site's
|
||||||
|
# all-hosts aggregate, this host's own access group, and god_admin.
|
||||||
|
ldap_access_groups=( "site_\${ldap_location}_hosts_access" "site_\${ldap_location}_host_\$(hostname)_access" "god_admin" )
|
||||||
LDAPVARS
|
LDAPVARS
|
||||||
else
|
else
|
||||||
info " ldap-client/ldap.vars exists -- keeping it"
|
info " ldap-client/ldap.vars exists -- keeping it"
|
||||||
|
|||||||
+1
-1
Submodule sso-manager-node updated: 8db00f0ed6...e8d04203c3
Reference in New Issue
Block a user