Heimdall Identity Aware Proxy

repository·main·Indexed 42 days ago

https://github.com/dadrus/heimdall

A cloud-native Identity Aware Proxy and Access Control Decision service for Zero Trust architectures. Heimdall provides a configurable pipeline for authentication, contextualization, and authorization to secure HTTP services. It can operate as a standalone proxy or as a decision service integrating with gateways such as Envoy, Traefik, Istio, NGINX, and HAProxy.

Tokens
73.6K
Snippets
203
Records
272
Agent score
53%

What's inside Heimdall

  1. What is Heimdall?

    main

    Heimdall is a cloud-native Identity Aware Proxy (IAP) and Access Control Decision service designed to help you adopt a Zero Trust architecture. It allows you to authenticate, enrich, and authorize incoming HTTP requests at any level of your infrastructure without requiring you to learn new protocols or integrate complex authentication/authorization frameworks directly into your application code.

    Key capabilities include:

    • Authentication & Authorization: Integrate with existing systems like OpenID Connect, OAuth2, Open Policy Agent (OPA), OpenFGA, and Ory Keto.
    • Request Enrichment: Dynamically add context (e.g., user data) to incoming requests to simplify downstream authorization decisions.
    • Declarative Security: Define security logic using familiar declarative techniques (like Kubernetes Custom Resources).
    • Pipeline Execution: Use Common Expression Language (CEL) to implement complex pipeline logic and authorization steps.
  2. What is a Rule Provider?

    main

    A Rule Provider is the component in Heimdall that manages the lifecycle of authentication and authorization rules. Its primary responsibilities include:

    • Loading: Fetching rules from a source.
    • Reloading: Detecting changes and updating the active rule set.
    • Removal: Cleaning up rules when they are deleted from the source.

    Providers act as the bridge between your rule storage (files, APIs, cloud storage, or Kubernetes) and Heimdall's enforcement engine.

  3. Rule Types: Regular vs. Default Rules

    main

    Heimdall supports two types of rules:

    • Upstream specific rule (Regular rule): Dynamic rules that match specific requests. They can appear or disappear alongside the upstream services they define.
    • Default rule: An optional rule that serves two purposes:
      1. Acts as a base for regular rules to inherit behavior from.
      2. Is executed if no other regular rule matches the incoming request.

    Note on Inheritance: You cannot override individual mechanisms within a stage. If you define any mechanism for a given stage (e.g., authentication) in a rule's pipeline, the entire stage definition replaces the inherited one from the default rule.

  4. Extract Authentication Data from Requests

    main

    Heimdall uses an Authentication Data Source to retrieve credentials from an incoming request. This is a list of strategies executed in order; subsequent strategies act as fallbacks if the previous one fails to find data.

    Available Strategies:

    • Cookie Strategy: Extracts data from a specific cookie. Requires cookie (name).
    • Header Strategy: Extracts data from an HTTP header. Requires header (name). Optionally supports scheme (e.g., Bearer).
    • Query Parameter Strategy: Extracts data from a query parameter. Requires query_parameter (name).
    • Body Parameter Strategy: Extracts data from the request body (JSON or application/x-www-form-urlencoded). Requires body_parameter (name).
    - header: Authorization
      scheme: Bearer
    - query_parameter: access_token
    - body_parameter: access_token
  5. Understand the Heimdall Management Service

    main

    The Management Service is an always-exposed service in Heimdall that provides endpoints for health monitoring and retrieving the JSON Web Key Sets (JWKS) used for JWT creation.

    By default, the service listens on 0.0.0.0:4457 and applies standard default timeouts and buffer limits. It is used to monitor the health of the Heimdall instance and to allow other services to fetch the public keys required to validate JWTs issued by Heimdall.

  6. Configure Redis cache backends

    main

    Heimdall supports Redis as a distributed cache via three types: redis (single instance), redis-cluster, and redis-sentinel. All Redis backends use pipelining for performance and support client-side caching by default.

    Common Redis Settings

    All Redis types support these options under config:

    • credentials (Secret Reference, optional): Reference to credentials containing username (optional) and password.
    • client_cache (object, optional): Configures client-side caching to reduce roundtrip time.
      • disabled (boolean, optional): Defaults to false.
      • ttl (Duration, optional): Maximum TTL on the client side. Capped by the server's TTL.
      • size_per_connection (ByteSize, optional): Size per TCP connection. Defaults to 128MB.
    • buffer_limit (object, optional): Read/write buffer limits for connections.
      • read (ByteSize, optional): Max size for read buffer. Defaults to 0.5MB.
      • write (ByteSize, optional): Max size for write buffer. Defaults to 0.5MB.
    • timeout (object, optional):
      • write (Duration, optional): Max duration before timing out writes. Defaults to 150s.
    • max_flush_delay (Duration, optional): Pauses the pipeline write loop after flushing to allow more commands to collect. Reduces CPU usage but increases latency. Defaults to 0s.
    • tls (object, optional): TLS settings. Communication is TLS by default.
      • disabled (boolean, optional): Disables TLS. Defaults to false. Note: Can only be true if Heimdall is started with --insecure-skip-egress-tls-enforcement.
  7. Use Rule Inheritance to override default rule stages

    main

    Heimdall allows specific (regular) rules to inherit parts of the default_rule configuration. This is useful for defining a global security baseline and only overriding the specific stage that needs to change (e.g., changing authorization from deny_all to allow_all).

    Example: Inheriting Authentication and overriding Authorization

    1. Define a Default Rule that denies everything by default:
    default_rule:
      execute:
        - authenticator: session_cookie_from_kratos_authn
        - authorizer: deny_all_requests_authz
    1. Define a Specific Rule that matches a path and only overrides the authorizer stage. Because execute is provided but only contains an authorizer, it inherits the authenticator from the default_rule:
    id: rule:my-service:protected-api
    match:
      http:
        paths:
          - path: /foo
    execute:
      - authorizer: allow_all_requests_authz
  8. Understand RuleSet schema conversion limitations

    main

    Starting with v0.18.0, Heimdall provides automated structural schema conversion for RuleSet definitions via a convert CLI command or a Kubernetes conversion controller.

    Important Limitations:

    • Structural only: The converter only handles changes to the schema structure (renamed, moved, or restructured properties).
    • No semantic rewriting: It cannot interpret or rewrite user-defined content such as Go templates, CEL expressions, or other mechanism-specific values.
    • Manual steps required: Because user-defined logic (like template paths) might change semantically, you must always check the release notes for manual migration steps in addition to running the converter.

    Example of a semantic change: In v0.18.0, the Outputs evaluation object changed. Previously, results were accessed via {{ .Outputs.foo.bar }}. Now, they must be accessed via {{ .Outputs.foo.Payload.bar }}. The converter will not automatically update these strings inside your templates.

  9. Heimdall deployment modes and integration options

    main

    Heimdall is designed to be flexible in how it is deployed within your infrastructure. You can choose between:

    • Standalone Proxy: Heimdall acts as the primary entry point for authentication and authorization.
    • Integrated Proxy: Heimdall is integrated with your existing infrastructure, such as proxies, API gateways, or ingress controllers. You do not need to replace your existing tools; Heimdall can work alongside them to add advanced security capabilities.
  10. What are Finalizers in Heimdall

    main
    Finalizers are the last steps executed in a rule pipeline. Their primary purpose is to create a special representation of the Subject (the authenticated entity) or other pipeline data to make it available to the upstream service. Common use cases include transforming subject attributes into HTTP headers, cookies, or JWT claims, or performing OAuth2 client credentials flows to obtain access tokens.
  11. How to use mechanisms in rules

    main

    To use a mechanism within a rule, you must follow a two-step process:

    1. Define/Configure the Mechanism: Mechanisms are generic and must be defined in a Mechanisms Catalogue first. This step allows you to configure specific identity management systems, set default behaviors, and ensure secure communication only with allowed systems.
    2. Reference in Rules: Once defined in the catalogue, you can create rules that simply reference these mechanisms. You can "tune" the configuration within the rule if necessary, but you cannot use a mechanism that has not been previously defined in the catalogue.

    Key Constraint: If you do not define any mechanisms in the catalogue, you cannot define any rules.

  12. How rule inheritance works (Default Rule vs. Regular Rule)

    main

    Heimdall uses a polymorphic approach to rule configuration. Rules can inherit behavior from a DefaultRule to minimize configuration redundancy.

    Inheritance Logic

    • If no Default Rule is defined: A regular rule inherits from a system BaseRule. It must implement the required stages (like executeAuthenticationStage).
    • If a Default Rule is defined: A regular rule can inherit from the DefaultRule. This allows the regular rule to only specify the stages that differ from the default.

    Important Constraint

    You cannot override individual mechanisms within a stage. Once you define any mechanism for a given stage in a rule's pipeline, the entire stage definition replaces the inherited one.

    For example, if your DefaultRule has both Authentication and Authorization, and your SpecificRule only defines Authentication, the SpecificRule will use the new Authentication mechanism but will lose the inherited Authorization mechanism (it will revert to the system BaseRule behavior for that stage).