Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions roles/eda/tasks/deploy_eda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@
definition: "{{ lookup('template', 'eda.configmap.yaml.j2') }}"
wait: yes

- name: Set gateway and controller hostnames for NO_PROXY exclusion
ansible.builtin.set_fact:
_gateway_hostname: >-
{{ extra_settings | default([]) | selectattr('setting', 'equalto', 'EDA_ANSIBLE_BASE_JWT_KEY')
| map(attribute='value') | select | list | first | default('')
| urlsplit('hostname') }}
Comment on lines +31 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg 'roles/eda/(tasks/deploy_eda.yml|templates/(eda\.configmap\.yaml\.j2|eda-proxy-env\.configmap\.yaml\.j2))|deploy_eda\.yml|extra_settings' || true

echo "== target file excerpt =="
cat -n roles/eda/tasks/deploy_eda.yml | sed -n '1,70p' || true

echo "== template excerpts =="
for f in roles/eda/templates/eda.configmap.yaml.j2 roles/eda/templates/eda-proxy-env.configmap.yaml.j2; do
  if [ -f "$f" ]; then
    echo "--- $f ($(wc -l < "$f") lines) ---"
    cat -n "$f" | sed -n '1,80p'
  fi
done

echo "== setting references =="
rg -n "extra_settings|EDA_ANSIBLE_BASE_JWT_KEY|gateway|NO_PROXY|_gateway_hostname|ansible_base|urlsplit" roles/eda -S || true

Repository: ansible/eda-server-operator

Length of output: 9375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg 'roles/eda/(tasks/deploy_eda.yml|templates/(eda\.configmap\.yaml\.j2|eda-proxy-env\.configmap\.yaml\.j2))|deploy_eda\.yml|extra_settings' || true

echo "== target file excerpt =="
cat -n roles/eda/tasks/deploy_eda.yml || true

echo "== template excerpts =="
for f in roles/eda/templates/eda.configmap.yaml.j2 roles/eda/templates/eda-proxy-env.configmap.yaml.j2; do
  if [ -f "$f" ]; then
    echo "--- $f ($(wc -l < "$f") lines) ---"
    cat -n "$f" | sed -n '1,100p'
  fi
done

echo "== setting references =="
rg -n "extra_settings|EDA_ANSIBLE_BASE_JWT_KEY|gateway|NO_PROXY|_gateway_hostname|ansible_base|urlsplit" roles/eda -S || true

echo "== deterministic urlsplit behavior probe =="
python3 - <<'PY'
from urllib.parse import urlsplit
samples = [
    "jwt-secret-is-not-a-url",
    "https://gateway.example.net",
    "https://gateway.example.net/sso/",
    "http://gateway.example.net:443/",
    "  ",
]
for s in samples:
    print(repr(s), "=>", repr(urlsplit(s).hostname))
PY

Repository: ansible/eda-server-operator

Length of output: 13670


🌐 Web query:

EDA_ANSIBLE_BASE_JWT_KEY Ansible Base JWT key configuration EDA

💡 Result:

The EDA_ANSIBLE_BASE_JWT_KEY is an environment variable used to configure the JSON Web Token (JWT) settings for Event-Driven Ansible (EDA) [1]. It is primarily associated with the django-ansible-base (DAB) library, which is integrated into the EDA server to handle authentication, Role-Based Access Control (RBAC), and resource registry functions [2]. In containerized or development environments, such as those defined in docker-compose configurations, this variable is used to set the key or URL source for JWT validation [1]. Its default value is typically set to 'https://localhost' in many deployment templates [1]. Important technical context regarding JWT and authentication in Event-Driven Ansible includes: 1. Authentication Mechanisms: Event-Driven Ansible supports various authentication methods including OAuth tokens (JWT), basic authentication, and session cookies for API access [3]. 2. Purpose of JWT in EDA: JWTs are used for secure communication, including WebSockets and activation command pathways [4]. They are managed through the django-ansible-base library, ensuring consistent authentication across the platform [2]. 3. Configuration Precedence: Like other Ansible-related configurations, settings can be managed via environment variables, configuration files (e.g., ansible.cfg), or command-line parameters, depending on the specific component and deployment architecture [5]. 4. Related Variables: In addition to the base JWT key, there are related configuration variables such as EDA_ANSIBLE_BASE_JWT_VALIDATE_CERT, which determines whether the system validates the certificate of the JWT issuer [1]. For specific implementation needs, refer to the documentation of the environment or deployment method you are using (such as the EDA server operator or container-based installation) to ensure the variable is defined correctly within the appropriate scope [2].

Citations:


🌐 Web query:

site-packages django_ansible_base jwt_settings JWT_KEY URL provider

💡 Result:

django-ansible-base is a library designed to provide a foundational structure for Ansible-related applications built on Django [1][2]. Regarding your specific keywords, there is no single monolithic "jwt_settings" configuration object named exactly that within the core library; rather, JWT-related configurations are managed through specific plugin settings or application-level integrations [3][4]. 1. JWT Settings and Keys: Authentication plugins in django-ansible-base, such as OIDC, utilize settings like JWT_ALGORITHMS and JWT_DECODE_OPTIONS for token validation [3]. In implementations like AWX (which leverages this library), token management is often defined via a custom JWT_SETTINGS dictionary in the application's Django settings, specifying parameters such as ACCESS_TOKEN_LIFETIME, ALGORITHM (e.g., RS256), SIGNING_KEY, and VERIFYING_KEY [4][5]. 2. URL Provider: The library uses a dynamic URL loading system to integrate endpoints from various apps [6]. Developers define URLs in an app's urls.py, categorized as api_version_urls, api_urls, or root_urls, which the library then manages [6]. There is no specialized "URL provider" object; instead, applications configure routing through these standard Django URL patterns and the library's dynamic loaders [6]. If you are developing an application using this library, you should refer to the documentation in the docs/ directory of the repository for specific implementation guidance on authentication and routing, as configurations often depend on the specific plugins and extra components (such as jwt-consumer) installed [2][7][6].

Citations:


🌐 Web query:

django-ansible-base JWT_PROVIDERS JWT_KEY local JWT_PROVIDERS source

💡 Result:

In the context of the django-ansible-base library, there is no generic global setting named JWT_PROVIDERS or JWT_KEY defined for top-level configuration in the project's core documentation [1][2][3]. The concepts of JWT providers and keys are implemented within specific authenticator plugins rather than as a global framework setting [4]. For example, in the OIDC (OpenID Connect) authenticator plugin, JWT processing relies on specific configuration fields such as: - JWT_ALGORITHMS: Specifies the algorithms used for decoding JWT responses from the Identity Provider (IDP) [4]. - JWT_DECODE_OPTIONS: Defines options for token validation and processing [4]. When these plugins receive a JWT (often via an Authorization header with a Bearer token), they use a public key or secret to decode and validate the token [4]. If you are encountering these terms, they are likely specific to: 1. A custom implementation or a specific feature component (like jwt_consumer) within a project using django-ansible-base [3][5]. 2. A misunderstanding of configuration schemas, where settings are defined on a per-authenticator basis in the database or settings files, rather than as a global JWT_PROVIDERS dictionary [4]. If you are developing a feature that requires custom JWT handling, it should be implemented as a library or Django app following the project's architecture, rather than relying on a global JWT_PROVIDERS setting [1]. Please verify the specific authenticator configuration documentation for the plugin you are using, as requirements vary by implementation (e.g., OIDC vs. other custom JWT authenticators) [4].

Citations:


🌐 Web query:

"ansible_base.jwt_consumer" "JWT_KEY" "jwt_consumer"

💡 Result:

The term ansible_base.jwt_consumer refers to a component within the django-ansible-base library [1][2], which provides centralized authentication and shared functionality for Red Hat Ansible Automation Platform (AAP) services, such as Automation Controller (AWX) [3][4]. The jwt_consumer module is responsible for handling JSON Web Token (JWT) based authentication [2][3]. It allows backend services to verify and consume tokens, typically issued by a platform gateway or identity provider [5][3]. Key aspects regarding JWT_KEY and jwt_consumer include: 1. Usage in Authentication: When AAP services (like Controller) are deployed within the platform architecture, they often use AwxJWTAuthentication (provided by ansible_base.jwt_consumer) as the primary authentication class [3][4]. This mechanism ensures that requests are authenticated via JWTs, effectively locking out legacy methods like Basic or Session authentication in certain deployment modes [3]. 2. Configuration and Keys: The platform gateway manages the signing and verification of these tokens [5]. Configuration often involves defining the allowed algorithms (JWT_ALGORITHMS) [6][7] and handling the public keys used for decryption [6][5]. If your environment encounters authentication failures, ensure that the JWT algorithms are correctly configured in your identity provider or platform gateway settings [7]. 3. Technical Context: In the context of the django-ansible-base codebase, you will find this module under ansible_base/jwt_consumer [1][2]. It integrates with frameworks like Django Rest Framework to provide seamless authentication across the platform [8][4]. If you are seeing errors mentioning X-DAB-JW-TOKEN, it typically indicates that a request is missing the required JWT header or that the token validation is failing due to a configuration mismatch (e.g., missing public key or unsupported algorithm) [9][6].

Citations:


🌐 Web query:

"AWS_DAB_JWT" "DAB_JWT" "jwt_consumer" site:github.com/ansible

💡 Result:

In the context of Red Hat Ansible Automation Platform (AAP) and the django-ansible-base (DAB) library, jwt_consumer and related terms refer to the authentication mechanism used to secure API communication between components, specifically when integrating with an AAP Gateway [1][2]. Key concepts include: - jwt_consumer: This is a package within django-ansible-base that provides functionality for applications (like AWX/Controller) to consume and validate JSON Web Tokens (JWTs) [1][2]. It includes authentication classes, such as AwxJWTAuthentication, which verify incoming requests against tokens issued by a centralized gateway [2][3]. - X-DAB-JW-TOKEN: This is a header used to pass the JWT in HTTP requests [4][5]. When AAP is configured to use gateway-based authentication, the gateway attaches this token to requests. If the header is missing or the token is invalid, applications will typically return 403 Forbidden or 401 Unauthorized errors [4][6]. - Enforcement: In modern AAP deployments, the configuration can enforce "JWT-only" authentication for the Controller [3][7]. When RESOURCE_SERVERURL is set, the application overrides its default authentication classes to use ansible_base.jwt_consumer.awx.auth.AwxJWTAuthentication exclusively, ensuring all requests are authenticated via the platform gateway and blocking legacy authentication methods like Basic or Session auth [3]. These components are part of the broader effort to standardize security and authentication across different services within the Ansible Automation Platform, ensuring that components communicate securely through a common gateway rather than relying on direct, unauthenticated, or legacy-method API access [3][5].

Citations:


🌐 Web query:

"EDA_ANSIBLE_BASE_JWT_PROVIDER_URL" "EDA_ANSIBLE_BASE_JWT_KEY"

💡 Result:

The environment variables EDA_ANSIBLE_BASE_JWT_PROVIDER_URL and EDA_ANSIBLE_BASE_JWT_KEY are configuration settings used in Event-Driven Ansible (EDA) to manage JSON Web Token (JWT) authentication [1][2]. They are typically utilized within the context of the django-ansible-base (DAB) library, which the EDA server uses to handle identity and access management (RBAC, JWT authentication, and resource registry) [2]. EDA_ANSIBLE_BASE_JWT_PROVIDER_URL: This variable is used to configure the URL of the external identity provider or authentication service that the system communicates with to validate or retrieve JWT-related information. EDA_ANSIBLE_BASE_JWT_KEY: This variable typically specifies the cryptographic key (or the path/location of the key) used for signing or verifying JWTs within the application. In some deployment configurations, such as development or staging docker-compose files, this variable may be set to a default value like https://localhost if not explicitly provided [1]. These settings are part of the broader infrastructure for managing authentication in Event-Driven Ansible, ensuring that services like the rulebook engine, web API, and WebSocket consumers can securely verify user and service identity [3][2]. Because these are platform-level authentication configurations, they are distinct from, and should not be confused with, variable naming conventions used by third-party tools (such as certain Terraform providers for EDA) [4]. For production deployments, these configurations are managed through the system's deployment tools, such as the EDA server operator [2].

Citations:


Use a URL-valued setting for the NO_PROXY gateway hostname.

EDM_ANSIBLE_BASE_JWT_KEY is a JWT configuration value, and when its value is not a URL urlsplit('hostname') returns None, so _gateway_hostname is empty and the gateway hostnames are not added to NO_PROXY. Derive this from the configured JWT provider/gateway URL instead, and keep the setting-name comparison in sync with the item.setting | upper normalization in the ConfigMap template.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@roles/eda/tasks/deploy_eda.yml` around lines 31 - 33, The NO_PROXY gateway
hostname currently derives from the JWT key value instead of a URL setting.
Update the `_gateway_hostname` expression in the deploy task to select the
configured JWT provider/gateway URL, apply `urlsplit('hostname')`, and align the
setting-name comparison with the ConfigMap template’s `item.setting | upper`
normalization.

Source: Path instructions

_controller_hostname: "{{ automation_server_url | default('') | urlsplit('hostname') }}"

- name: Apply proxy environment ConfigMap
k8s:
apply: yes
Expand Down
15 changes: 12 additions & 3 deletions roles/eda/templates/eda-proxy-env.configmap.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ data:
HTTPS_PROXY: '{{ https_proxy }}'
https_proxy: '{{ https_proxy }}'
{% endif %}
{% if no_proxy %}
NO_PROXY: '{{ no_proxy }}'
no_proxy: '{{ no_proxy }}'
{% if http_proxy or https_proxy or no_proxy %}
{% set _no_proxy_list = (no_proxy | default('')).split(',') | map('trim') | select | list %}
{% set _required = ['localhost', '127.0.0.1', '::1', '[::1]', '.svc', '.svc.cluster.local', ansible_operator_meta.name, ansible_operator_meta.name + '.' + ansible_operator_meta.namespace, ansible_operator_meta.name + '-api', ansible_operator_meta.name + '-api.' + ansible_operator_meta.namespace, ansible_operator_meta.name + '-daphne', ansible_operator_meta.name + '-daphne.' + ansible_operator_meta.namespace] %}
{% if _gateway_hostname | default('') %}
{% set _required = (_required + [_gateway_hostname, _gateway_hostname + '.' + ansible_operator_meta.namespace]) | unique %}
{% endif %}
{% if _controller_hostname | default('') %}
{% set _required = (_required + [_controller_hostname, _controller_hostname + '.' + ansible_operator_meta.namespace]) | unique %}
{% endif %}
{% set _augmented = (_no_proxy_list + _required) | unique | join(',') %}
NO_PROXY: '{{ _augmented }}'
no_proxy: '{{ _augmented }}'
{% endif %}
Loading