Skip to main content
Skip table of contents

Advanced APISIX Routing: A Guide to Create Exception Routes via Helm

This guide will equip users with the understanding and practical steps to define "exception routes" in APISIX using Helm values.yaml. This allows specific sub-paths of a service to have different routing behaviors (e.g., bypassing authentication) than the main service route.

Introduction to Exception Routes

A. What is an Exception Route?

An exception route is a specialized APISIX route configuration that overrides the default or general routing behavior for a very specific subset of traffic targeting a service. Think of it like a special access lane on a highway that has different rules than the main lanes, but only for specific vehicles or destinations. For our services managed by APISIX, this means a particular URL path might bypass standard authentication, have unique rewrite rules, or different security policies.

B. Why Use Exception Routes? (Purpose & Use Cases)

Exception routes provide granular control and are typically used for:

  • Public Endpoints: Exposing specific API paths (e.g., /service/api/v1/public/status, /service/webhooks/external-system) that should not require user authentication, while the rest of the service remains secured.

  • Specific Authentication Schemes: Applying a different authentication method (e.g., API key) to one endpoint while others use OIDC.

  • Custom URL Rewriting: Supporting legacy URL paths by rewriting them to new backend structures, or creating user-friendly vanity URLs for specific functionalities.

  • Targeted Security Policies: Applying stricter rate-limiting or IP whitelisting to sensitive administrative sub-paths.

  • Unique CORS Policies: Allowing cross-origin requests from specific domains for certain API endpoints but not others.

  • A/B Testing or Canary Releases: Directing a small fraction of traffic for a particular path to a new version of a service.

C. How it Works with APISIX & Helm

In your environment, APISIX routes are defined within the apisixRoutes list in the relevant component's section of your Helm values.yaml file. When a request arrives:

  1. APISIX evaluates potential matching routes based on criteria like path, method, headers, etc.

  2. If multiple routes match, the route with the highest priority value is chosen (higher number means higher precedence).

  3. The plugins configured for that chosen route are then executed.

To create an exception, you define a new route for the specific path with a higher priority than the general route for that service, and then customize its plugins block.

Before Creating an Exception Route: Key Considerations

Thoughtful planning before adding an exception route can prevent headaches and security issues down the line.

A. Is an Exception Truly Necessary?

  • Alternatives: Could the desired behavior be implemented within the application logic itself? Can existing plugins be configured more flexibly?

  • Simplicity: Strive to keep the gateway configuration as simple as possible. Each exception adds a layer of complexity.

B. Security Implications (⚠️ CRITICAL)

  • Bypassing Authentication: This is the most common use case for exceptions but also the riskiest.

    • Thoroughly vet the endpoint: Ensure it reveals no sensitive data and does not allow any state-changing operations that could be exploited.

    • Principle of Least Privilege: The exception should grant the absolute minimum necessary access.

  • Modifying Other Security Plugins: If you're also disabling or altering rate limiting, IP restrictions, or other security plugins for the exception path, understand the cumulative risk.

C. Scope Definition

  • Path Specificity: Be as precise as possible with your paths. An overly broad path (e.g., /service/public/*) could unintentionally expose more than intended if new sub-paths are added later. Prefer specific paths like /service/public/resource-info.

  • HTTP Methods: Does the exception need to apply to all methods (GET, POST, PUT, DELETE, etc.), or only one or two (e.g., GET for public data, POST for an unauthenticated webhook)? Specify this in the methods array of the route if necessary.

  • Other Conditions: While your current Helm structure primarily focuses on paths and methods for matching, APISIX itself can match on headers, query parameters, and more. If an exception needs to be highly conditional, direct APISIX CRD modification might be needed if not expressible via current Helm templates.

D. Impact on Existing Routes & Services

  • Priority Conflicts: Map out the priorities of existing routes for the component. Ensure your new exception route has a distinctly higher priority to be evaluated first but doesn't clash with other high-priority routes in an unexpected way.

  • Unintended Overrides: A poorly defined exception (e.g., a too-generic path with high priority) could "steal" traffic intended for other routes or even other services if paths are not carefully namespaced.

E. Maintainability & Documentation

  • Clarity: Use a very descriptive nameSuffix for the route so its purpose is immediately obvious (e.g., login-unsecured, webhook-external-system-noauth).

  • Internal Documentation: Crucially, maintain a log or dedicated documentation page (e.g., in Confluence) detailing each exception:

    • What service it's for.

    • The specific path(s).

    • The reason for the exception and its intended behavior.

    • Who requested/approved it and when.

    • Any associated risks and mitigations.

  • Lifecycle Management: Is the exception permanent or temporary? If temporary, set a review date or a plan for its removal to prevent obsolete exceptions from accumulating.

Pros and Cons of Using Exception Routes

Pros

Cons

Flexibility: Fine-grained control over specific API paths without altering application code.

Increased Complexity: More routes can make the gateway configuration harder to manage and reason about.

Targeted Policies: Apply different security, rewrite, or CORS rules precisely where needed.

Potential Security Holes: Incorrectly configured exceptions (especially those bypassing auth) can inadvertently create vulnerabilities.

Decoupling: Handles some cross-cutting concerns (like public access) at the gateway layer.

Debugging Challenges: Tracing requests through multiple route possibilities can be more complex.

Rapid Adjustments: Quickly enable/disable access or change behavior for sub-paths via Helm value changes.

Configuration Obscurity: Overuse can make the overall system's behavior less obvious from application code alone. The gateway's role becomes critical.

Simplified App Logic: Applications might not need to handle every edge case for exposure if the gateway manages it.

Maintenance Overhead: Requires careful documentation, review, and cleanup of obsolete exceptions.

How to Add an Exception Route (Practical Steps & Example)

Let's walk through adding an exception to the agent-manager service. Assume the main /agent-manager/* path requires authentication (as per global.apisix.keycloak defaults when enableAuth: true), but we want to expose /agent-manager/public-status without authentication.

A. Locate Component & apisixRoutes in values.yaml

Find the agent-manager section in your Helm values.yaml file.

B. Define the New Exception Route

You will add a new YAML dictionary (an item starting with - ) to the apisixRoutes list for agent-manager. For readability, it's good practice to place higher priority (exception) routes before lower priority (general) routes within the list for that component.

Example values.yaml modification for agent-manager:

CODE

agent-manager:
  # ... other agent-manager settings ...
  apisixRoutes:
    # --- START: New Exception Route for Public Status ---
    - nameSuffix: "public-status-noauth"     # 1. Clearly identifies the exception's purpose
      enabled: true                         # 2. Route is active
      priority: 10                          # 3. HIGHER priority than the main route below
      paths: ["/agent-manager/public-status"] # 4. The specific path for this exception
      # methods: ["GET"]                    # 5. Optional: Restrict to GET if only status retrieval
      backendServicePort: 3000              # 6. Usually targets the same backend service
      plugins:                              # 7. Define the exceptional behavior
        enableAuth: false                   # << CRITICAL: Authentication is DISABLED for this path
        enableRewrite: true                 # Example: still strip /agent-manager prefix
                                            # so backend receives /public-status.
                                            # If the backend expects the full path, or a different
                                            # rewrite, adjust 'rewriteStripPrefix', 
                                            # 'rewriteRegexUriFrom'/'To' as needed.
        # enableCors: true                  # Optionally, define specific CORS if this public path
        # corsAllowOrigins: "*"             # needs broader access than other agent-manager paths.
        # customPlugins: []                 # Any other plugins specific to this exception
    # --- END: New Exception Route ---

    # Existing main "secured" route for agent-manager (conceptual example)
    - nameSuffix: "secured-main"
      enabled: true
      priority: 0                           # Lower priority, acts as a general rule for /agent-manager/*
      paths: ["/agent-manager/*"]           # Matches requests not caught by higher priority routes
      backendServicePort: 3000
      plugins:
        enableAuth: true                    # Main access to agent-manager requires authentication
        enableRewrite: true                 # Standard prefix stripping (backend sees /*)
        enableCors: true                    # Default CORS behavior for this service
        # ... other standard plugins for agent-manager ...
    

Explanation of Key Fields for the Exception Route:

  • nameSuffix: "public-status-noauth": Helps create a unique and understandable APISIX route name (e.g., ef-cx-agent-manager-public-status-noauth).

  • priority: 10: This ensures APISIX evaluates this route before the secured-main route (which has priority: 0). If a request comes for /agent-manager/public-status, this route will match first.

  • paths: ["/agent-manager/public-status"]: This route only applies to requests for this exact path.

  • plugins.enableAuth: false: This is the core of the exception for this example – it tells APISIX not to enforce the default authentication (e.g., Keycloak OIDC defined in global.apisix.keycloak) for this specific path.

After the Modification: What to Expect & Verify

Once you've added the exception route definition to your values.yaml and deployed the changes (e.g., via helm upgrade):

A. Expected Behavior

  • Requests to the exception path (e.g., https://<your-fqdn>/agent-manager/public-status) should now operate under the new plugin rules (e.g., accessible without an authentication token).

  • Requests to all other paths under /agent-manager/* (e.g., https://<your-fqdn>/agent-manager/some-other-api) should still be governed by the original, lower-priority "secured-main" route and its plugins (e.g., still require authentication).

  • Traffic to entirely different services/components should be completely unaffected.

B. Verification Steps (🧪 CRITICAL)

Always test thoroughly after deploying changes!

  1. Test the Exception Path:

    • Use a tool like curl, Postman, or your browser.

    • Access the exception URL (e.g., https://<your-fqdn>/agent-manager/public-status).

    • Verify that it behaves as expected (e.g., you get a successful response without providing an auth token if enableAuth: false).

    • If you configured specific rewrites or custom plugin behaviors, verify those too.

  2. Test Non-Exception Paths (for the same component):

    • Access other URLs for the same component (e.g., https://<your-fqdn>/agent-manager/some-secured-data).

    • Verify they still adhere to the original rules (e.g., prompt for authentication or return a 401/403 if no token is provided).

  3. Test Other Services:

    • Make a few sample requests to unrelated services to ensure they haven't been inadvertently affected.

  4. Check Logs (If Accessible):

    • APISIX Logs: If you have access, APISIX logs can show which route was matched for a given request and which plugins were applied. This is very useful for debugging.

    • Application Logs: Check the logs of the backend service (agent-manager in our example) to see if requests are arriving as expected (e.g., with the correct rewritten path, and without user identity information if authentication was bypassed at the gateway).

C. Troubleshooting Common Issues

  • Exception Not Working (Old behavior persists):

    • Priority: Double-check the priority value. Is it numerically higher than the general route?

    • Path Matching: Is the path in your test request exactly matching one defined in the paths array of your exception route? Check for trailing slashes, case sensitivity (paths are usually case-sensitive), or typos.

    • enabled: true: Confirm the exception route is enabled in the YAML.

    • Helm Deployment: Ensure your helm upgrade command was successful and the Kubernetes resources reflecting your changes (especially APISIX CRDs like ApisixRoute) were updated in the cluster. There can sometimes be a short delay for APISIX to pick up changes.

  • Exception Too Broad (Affecting other paths):

    • Your exception route's paths might be too generic. Make them more specific.

    • Re-evaluate priority if multiple custom routes could potentially overlap.

  • Security Vulnerability Introduced:

    • If an endpoint is exposed that shouldn't be, immediately disable the problematic exception route (enabled: false and redeploy) or fix its path/plugin configuration.

Best Practices & Maintaining Sanity

  • 🧘 Minimize Exceptions: Use them only when genuinely necessary. The more exceptions, the harder the system is to understand and maintain.

  • 🏷️ Clear Naming: Use descriptive nameSuffix values (e.g., login-unsecured, metrics-prometheus-only, webhook-systemX-noauth).

  • 🎯 Specificity is Key: Define paths (and methods if applicable) as narrowly and precisely as possible for your exceptions.

  • ✍️ Document Everything: For each exception route, maintain clear documentation (e.g., in Confluence, or as extensive comments in your values.yaml):

    • Its purpose and justification.

    • The component and specific path(s) it affects.

    • The exact plugin changes and why they are needed.

    • Any associated security considerations or approvals.

  • 🧐 Regular Audits: Periodically review all defined exception routes. Are they still necessary? Are they configured correctly according to current security best practices? Remove obsolete exceptions promptly.

  • 💾 Version Control: All values.yaml changes should be committed to Git (or your version control system), with clear commit messages explaining the addition, modification, or removal of exception routes.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.