Help us shape the future of Go! Take the 2026 Go Developer Survey

host-manager

module
v0.29.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: Apache-2.0

README

kdex-host

// TODO: Add simple overview of use/purpose

Description

// TODO: An in-depth paragraph about your project and overview of use

Getting Started

Prerequisites
  • go version v1.24.0+
  • docker version 17.03+.
  • kubectl version v1.11.3+.
  • Access to a Kubernetes v1.11.3+ cluster.
To Deploy on the cluster

Build and push your image to the location specified by IMG:

make docker-buildx-local PLATFORMS=linux/amd64 REPOSITORY=k3d-registry:5000 IMG=kdex-tech/kdex-host

NOTE: This image ought to be published in the personal registry you specified. And it is required to have access to pull the image from the working environment. Make sure you have the proper permission to the registry if the above commands don’t work.

Install the CRDs into the cluster:

make install

Deploy the Manager to the cluster with the image specified by IMG:

make deploy IMG=<some-registry>/kdex-host:tag

NOTE: If you encounter RBAC errors, you may need to grant yourself cluster-admin privileges or be logged in as admin.

Create instances of your solution You can apply the samples (examples) from the config/sample:

kubectl apply -k config/samples/

NOTE: Ensure that the samples has default values to test it out.

To Uninstall

Delete the instances (CRs) from the cluster:

kubectl delete -k config/samples/

Delete the APIs(CRDs) from the cluster:

make uninstall

UnDeploy the controller from the cluster:

make undeploy

Project Distribution

Following the options to release and provide this solution to the users.

By providing a bundle with all YAML files
  1. Build the installer for the image built and published in the registry:
make build-installer IMG=<some-registry>/kdex-host:tag

NOTE: The makefile target mentioned above generates an 'install.yaml' file in the dist directory. This file contains all the resources built with Kustomize, which are necessary to install this project without its dependencies.

  1. Using the installer

Users can just run 'kubectl apply -f ' to install the project, i.e.:

kubectl apply -f https://raw.githubusercontent.com/<org>/kdex-host/<tag or branch>/dist/install.yaml
By providing a Helm Chart
  1. Build the chart using the optional helm plugin
kubebuilder edit --plugins=helm/v1-alpha
  1. See that a chart was generated under 'dist/chart', and users can obtain this solution from there.

NOTE: If you change the project, you need to update the Helm Chart using the same command above to sync the latest changes. Furthermore, if you create webhooks, you need to use the above command with the '--force' flag and manually ensure that any custom configuration previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' is manually re-applied afterwards.

Auth Event Hooks (http-event-hook Secret)

The host-manager can notify (advisory) or gate (enforcing) external HTTP endpoints on auth lifecycle events — login, logout, login-failed, and session-refresh. One or more Secrets configure the hooks; each hook is a separate Secret, discovered by the kdexinternalhost controller alongside the http-lookup-auth Secret.

A Secret is picked up as an event hook when it:

  • is annotated with kdex.dev/secret-type: http-event-hook
  • is annotated with kdex.dev/active-key: "true"

Unlike http-lookup-auth (only the newest active one is used), every active http-event-hook Secret becomes a hook — multiple hooks may run side by side. When more than one enforcing hook subscribes to the same event, they are evaluated in Secret-name order (sorted lexicographically).

Data keys
key required default meaning
url yes — endpoint POSTed for each subscribed event
shared-secret yes — HMAC-SHA256 key; must be at least 32 raw bytes
events yes — comma-separated subset of login, logout, login-failed, session-refresh
mode no advisory advisory or enforcing; enforcing is only honored for login/logout — for login-failed/session-refresh it is silently treated as advisory (both are always fired async)
timeout-ms no 2000 integer milliseconds; bounds every call to this hook, sync and async
failure-mode no per-event (see below) fail-open or fail-closed; only meaningful for enforcing hooks
Request contract
POST <url>
Content-Type: application/json
X-K-CNAS-Event-Timestamp: <unix-millis>
X-K-CNAS-Event-Signature: hex(hmac-sha256(shared-secret, timestamp + "." + body))

The endpoint MUST verify the HMAC over timestamp + "." + body (same convention as the http-lookup-auth Secret's X-K-CNAS-Lookup-* headers).

Body envelope:

{
  "event": "login",              // login | logout | login-failed | session-refresh
  "timestamp": 1699999999999,    // unix millis, matches the signature timestamp
  "host": "acme.example",        // the KDexHost identity
  "subject": "alice",            // sub (the vouched subject; the typed name only for a login-failed before any credential matched); may be "" for logout when no token could be decoded
  "login_name": "Alice ",        // local logins only: the name as typed, which can differ from subject
  "auth_method": "local",        // local | oidc | ... (omitted when unknown)
  "client_id": "…",              // omitted when not applicable
  "scope": "openid profile …",   // omitted when not applicable
  "claims": { "…": "…" },        // populated for login/session-refresh (minus roles/entitlements, which are broken out below); best-effort/omitted for logout; absent for login-failed
  "roles": ["…"],                // omitted when empty
  "entitlements": ["…"],         // omitted when empty
  "session_id": "…",             // refresh/session id, where available; omitted otherwise
  "reason": "…"                  // login-failed only: why the login failed
}

Fields are omitempty — a hook only sees the keys that apply to the event that fired it. For logout, identity is recovered best-effort by decoding the refresh/session token before it is cleared; if no token is available, subject (and the other identity fields) are simply absent and the event still fires.

login and session-refresh payloads carry the caller's full claim set (claims/roles/entitlements), which may include PII such as email or profile data — a hook endpoint must be trusted and secured accordingly (TLS, network policy, credential handling for the shared secret) exactly as if it were an internal identity system.

Response contract

Read only for enforcing login:

{ "ok": true, "reason": "" }
  • ok: false denies the login; reason (default "denied" when empty) is surfaced as the login failure reason.
  • For advisory calls, all async-only events (login-failed, session-refresh), and enforcing logout, the response body is ignored — only delivery (a 2xx status that decodes) is tracked, and failures are logged, never surfaced to the caller.
JIT provisioning during the gate

An enforcing login hook may provision the subject (create its grants/memberships in the backing store) before returning ok: true. Such a grant is reflected in the first minted token, not only after a later refresh: once the gate passes, the login path re-resolves the subject's live backend claims (the resolve-url Lookup → claimMappings → entitlements, the same enrichment the refresh path applies) and mints from the enriched context. This applies to both the password (LoginLocal) and OIDC-callback (ExchangeToken) login paths. The re-resolve runs only when an enforcing login hook is configured, so deployments without one are unaffected. The hook does not return grants in its response — provisioning is delivered through the backing store the Lookup already reads, keeping the { ok, reason } contract above unchanged. (First-time provisioning is reflected immediately; re-provisioning an already-resolved subject within the resolve cache window lags to the next refresh.)

Advisory vs. enforcing, and failure modes
  • Advisory hooks fire in a background goroutine, best-effort, bounded by timeout-ms. A failure (timeout, dial error, non-2xx, decode failure) is logged and never affects the auth flow. login-failed and session-refresh are always dispatched this way, regardless of a hook's configured mode.
  • Enforcing login hooks run inline on the login path, sequentially in Secret-name order, short-circuiting on the first ok: false; every enforcing hook must return ok: true for the login to proceed (ErrLoginHookDenied). On a transport/timeout/decode failure, the effective failure-mode decides: default is fail-closed (deny the login with a generic reason) — only an explicit failure-mode: fail-open on that hook's Secret allows the login through when the hook is unreachable.
  • Subject-Secret logins are exempt from enforcing login hooks. A subject authenticated by a kdex.dev/secret-type: subject Secret (a KDexSubject, e.g. a break-glass admin) is a static, operator-authored account: enforcing login hooks are not called for it, regardless of failure-mode, and neither is the post-gate re-resolve (there is no gate to have provisioned anything). This keeps break-glass login working while the user manager behind a fail-closed hook is down. The exemption is logged at default verbosity (login exempt from enforcing login hooks, logger auth-event-hook); advisory login and login-failed hooks still fire. Subjects from every other source (http-lookup-auth, LDAP) remain gated.
  • Enforcing logout hooks run as sequential barriers, each bounded by its own timeout-ms, but never refuse the logout — a failure (or an ok: false response) is logged and logout proceeds regardless of failure-mode. Advisory logout hooks fire async afterward.

Contributing

// TODO(user): Add detailed information on how you would like others to contribute to this project

NOTE: Run make help for more information on all potential make targets

More information can be found via the Kubebuilder Documentation

License

Copyright 2025.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Directories

Path Synopsis
cli
ecdsa command
env command
paseto command
rsa command
auth/denial
Package denial implements host-manager's single denial contract.
Package denial implements host-manager's single denial contract.
job
rewrite
Package rewrite holds the pure path logic behind KDexPage rewrite mode (kdex-tech/host-manager#217), shared by the page controller's static placeholder check and the host's request-time dispatch.
Package rewrite holds the pure path logic behind KDexPage rewrite mode (kdex-tech/host-manager#217), shared by the page controller's static placeholder check and the host's request-time dispatch.
test

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL