Add vault integration for permanent users (break glass)#211
Closed
marcinpsk wants to merge 30 commits into
Closed
Conversation
- Python MAVIS external script (mavis_tacplus_keycloak.py) that authenticates against Keycloak using Resource Owner Password Credentials grant and maps Keycloak groups to TACACS+ membership - Multi-stage Dockerfile based on Debian Trixie to build tac_plus-ng with the Keycloak backend included - GitHub Actions workflow to build and push Docker image to GHCR - Sample tac_plus-ng configuration for Keycloak with admin/engineering/ readonly profiles
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Marcin Zieba <49913098+marcinpsk@users.noreply.github.com>
- Dockerfile: run as non-root tacplus user, force CC=clang, add CAP_NET_BIND_SERVICE guidance for port 49 - mavis_tacplus_keycloak.py: document JWT trust model in decode_jwt_payload, validate access_token key in token response, catch RequestException instead of broad Exception, sanitize group names against quote injection, add is_tacplus() bug workaround comment - Sample config: mark KEYCLOAK_URL as required, add explicit deny fallback in ruleset - CLAUDE.md: document is_tacplus() bug workaround in example pattern - .dockerignore: remove redundant entries already covered by *.md glob
Set up pre-commit with ruff (lint+format), markdownlint, hadolint, trailing-whitespace, end-of-file-fixer, check-yaml, and check-added-large-files. Fix hadolint-docker entry to include the hadolint command (image has no ENTRYPOINT). Add language specifiers to fenced code blocks in CLAUDE.md to satisfy MD040. Fix a bug in mavis_tacplus_keycloak.py where decode_token_claims() returning None (malformed/missing access_token) was not caught, allowing authentication to succeed without valid token claims. Now emits RESULT_FAIL and continues the loop. Remove the dead `if claims` guard on set_dn since None is handled earlier.
Move pre-commit and ruff from project dependencies to a dev dependency group. Remove uv-generated main.py boilerplate. Fix .envrc trailing whitespace and replace --extra dev with default dev group sync. Add .venv to .gitignore.
…failures Narrow the except block around error-response JSON parsing from broad Exception to (json.JSONDecodeError, ValueError) to avoid swallowing unrelated exceptions. Change the decode_token_claims None result from RESULT_FAIL to RESULT_ERROR since a server-side token decode failure is not a user auth rejection.
Narrow decode_token_claims except clause from broad Exception to (ValueError, json.JSONDecodeError, binascii.Error) to satisfy Ruff BLE001. Handle non-list group claims in extract_groups: wrap bare strings into a list, reject non-iterable types. Normalize KEYCLOAK_REQUIRE_GROUP at config load by stripping whitespace and leading slashes so it matches extract_groups output (fixes "/admin" never matching "admin").
Add Keycloak ROPC authentication backend, Dockerfile, and CI
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
…s/checkout-6 build(deps): bump actions/checkout from 4 to 6
Replace default code scanning setup with a custom workflow that actually builds the project, giving CodeQL access to generated headers and accurate preprocessor state.
Cache Keycloak groups in Redis/Valkey on AUTH success so that subsequent INFO and HOST requests (which lack a password) can return group membership without re-authenticating. This enables tac_plus-ng authorization and host-access rules for Keycloak users.
- Replace one-shot module-level Redis init with _get_redis() that
retries connections on each cache operation, with suppressed logging
after the first failure (logs again every 50th attempt).
- Scope cache keys by realm (tacplus:keycloak:{realm}:{user}) to
prevent collisions when multiple realms share the same Redis.
- Narrow exception handlers: redis.RedisError for Redis operations,
json.JSONDecodeError for corrupted cache payloads, with distinct
log messages for each.
- Make redis import conditional (try/except ImportError) so the script loads without python3-redis; caching is silently disabled. - Store sanitized (safe) groups in the cache instead of raw groups, removing duplicate sanitization on the INFO/HOST read path. - Return MAVIS_DOWN on cache miss for INFO/HOST instead of OK with no groups — without group data there is nothing useful to authorize.
- Reject KEYCLOAK_CACHE_TTL <= 0 at startup to prevent invalid setex. - Remove ping on every _get_redis() call; return existing client immediately and only ping when establishing a new connection. Callers invalidate _redis on RedisError so the next call reconnects. - Update fallthrough comment to "Unsupported request type". - Add workflow_dispatch trigger to CodeQL workflow.
Avoid blocking reconnect attempts on every cache call when Redis is down. _get_redis() now skips reconnection if fewer than 10 seconds have elapsed since the last attempt.
feat: add INFO/HOST authorization with Redis group cache
Add mavis_tacplus_vault.py that authenticates against HashiCorp Vault KV v2 using AppRole auth, intended as a fallback behind Keycloak in the MAVIS module chain. Includes in-process caching, Redis group persistence, and automatic token renewal. Add sample failover config (tac_plus-ng-keycloak-vault.cfg) showing the Keycloak→Vault chain with action error = continue, and documenting the setenv/execve environment gotcha.
Contributor
Author
|
sorry, wasn't meant for this repo. :) |
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.