hermes-agent/gateway
Ben Barclay f64e4f4f57
feat(gateway): generic OIDC client-credentials relay provisioning (NAS-free) (#60730)
For air-gapped / self-hosted-IdP deploys with NO Nous Portal, let the gateway
obtain its caller-identity bearer from a generic OAuth2 client_credentials grant
against the operator's own IdP (e.g. Microsoft Entra ID) instead of only
resolve_nous_access_token(). The connector's OIDC tenant resolver reads a claim
(default tid) off that token as the tenant.

- gateway/relay: new canonical _resolve_relay_identity_token() — client_credentials
  when gateway.idp.token_url (or GATEWAY_RELAY_IDP_* env) is set, else Nous Portal
  (unchanged default). Wired into self_provision_relay().
- hermes_cli/gateway_enroll: _resolve_identity_token() delegates to the canonical
  resolver so the enroll CLI and the runtime self-provision path share ONE impl.

Config via gateway.idp.{token_url,client_id,client_secret,scope} in config.yaml
(env override GATEWAY_RELAY_IDP_*). No behaviour change when unset.

Tests: tests/gateway/relay/test_identity_token_resolver.py (6 — mode selection,
request shape, config/env precedence, fail-closed). Relay suite 162 pass.

Validated via the cross-repo gateway<->connector live E2E (provision, managed
self-provision, inbound round-trip, /link) against a connector running the OIDC
tenant resolver with zero NAS config.
2026-07-08 16:55:32 +10:00
..
assets chore: limit generic status phrases to long-running notifications 2026-07-05 06:29:26 -07:00
builtin_hooks
platforms Add semantic titles for Discord auto-threads 2026-07-07 05:11:59 -07:00
relay feat(gateway): generic OIDC client-credentials relay provisioning (NAS-free) (#60730) 2026-07-08 16:55:32 +10:00
__init__.py
authz_mixin.py fix(gateway): per-profile pairing whitelist isolation in multiplex mode (#53045 salvage) (#59330) 2026-07-07 18:25:52 +10:00
cgroup_cleanup.py
channel_directory.py fix(gateway): only session-discover channel targets for connected platforms (#60574) 2026-07-07 17:04:32 -07:00
code_skew.py
config.py feat(gateway): GATEWAY_MULTIPLEX_PROFILES env override for multiplex flag (#60589) 2026-07-08 00:34:34 +00:00
cwd_placeholder.py fix(gateway): resolve terminal.cwd placeholders per backend and mount mode 2026-07-04 13:28:47 -07:00
dead_targets.py fix(gateway): skip confirmed-dead delivery targets (deleted groups, blocked bots) (#55115) 2026-06-29 13:23:29 -07:00
delivery.py refactor(gateway): share error-text blob between not_found classifiers 2026-07-01 15:11:38 +05:30
display_config.py fix: normalize display boolean strings 2026-07-05 06:29:26 -07:00
drain_control.py
hooks.py
kanban_watchers.py fix(kanban): route notifier wake via profile chokepoint; harden review findings 2026-07-02 00:05:48 +05:30
memory_monitor.py
message_timestamps.py
mirror.py refactor: consolidate gateway session metadata into state.db (#58899) 2026-07-05 14:01:03 -07:00
pairing.py fix: merge split gateway pairing stores 2026-07-07 02:18:17 -07:00
platform_registry.py
response_filters.py fix(gateway): tolerate punctuation on silence markers 2026-07-05 02:12:26 -07:00
restart.py
restart_loop_guard.py fix(gateway,cron): guard cron model-tool path + add auto-resume loop breaker (#30719) 2026-07-01 02:48:36 -07:00
rich_sent_store.py style(profile): frame comments around what the code does 2026-06-30 15:30:06 -07:00
run.py fix(gateway,cron): make shutdown drain visible to in-flight cron work 2026-07-07 22:15:04 -07:00
runtime_footer.py
scale_to_zero.py
session.py Add semantic titles for Discord auto-threads 2026-07-07 05:11:59 -07:00
session_context.py feat(kanban): route notifications via owning profile + wake creator agent 2026-07-02 00:05:48 +05:30
shutdown_forensics.py
slash_access.py
slash_commands.py fix(gateway): scope reset banners' session info to the serving profile (#59048 salvage) (#59329) 2026-07-07 18:25:45 +10:00
status.py fix(gateway): use process-level HERMES_HOME for identity files (#56993 salvage) (#59341) 2026-07-07 09:05:21 +00:00
status_phrases.py chore: limit generic status phrases to long-running notifications 2026-07-05 06:29:26 -07:00
sticker_cache.py
stream_consumer.py fix: make streaming reasoning-tag filter case-insensitive 2026-07-01 03:25:02 -07:00
stream_dispatch.py
stream_events.py
whatsapp_identity.py