News New Look, Same Vision: KrakenD’s Website Redesign

You are viewing a previous version of KrakenD Enterprise Edition (v2.3), go to the latest version

Document updated on Dec 12, 2022

Security Policies Playbook

An example is sometimes self-explanatory and lets you see the potential of the kind of stuff you can do with policies. The following examples demonstrate who to apply different policies to your API, but possibilities are endless!

Check if user has one of the selected roles (RBAC) or attributes (ABAC)

This configuration would go inside the endpoint’s extra_config. Checks that the role is admin or root, and that the department is also contained in a list:

{
  "extra_config": {
    "security/policies": {
      "jwt": {
        "policies": [
          "JWT.role in ['admin', 'root'] || JWT.permissions.can_write_users",
          "JWT.department in ['IT','HR']"
        ]
      }
    },
    "auth/validator": {
      "@comment": "Add here your auth/validator settings to enable 'jwt' policies"
    }
  }
}

Create a maintenance window

Disable requests between the 10am and noon on the 1st of January (UTC -5), and return a custom 500 status code:

{
  "extra_config": {
    "security/policies": {
      "req": {
        "policies": [
          "timestamp(now)< timestamp('2023-01-01T10:00:20.000-05:00') || timestamp(now)> timestamp('2023-01-01T12:00:20.000-05:00')"
        ],
        "error": {
          "body": "The system is down for maintenance",
          "status": 500
        }
      }
    }
  }
}

Endpoint lifecycle

You can decide to publish an endpoint on a specific date (or unpublish it). Here’s an example to deploy an endpoint on a old_version: true date:

{
  "extra_config": {
    "security/policies": {
      "req": {
        "policies": [
          "timestamp(now) > timestamp('2023-01-01T10:00:20.000-05:00')"
        ],
        "error": {
          "body": "The endpoint /foo is not yet implemented",
          "status": 404
        }
      }
    }
  }
}

User is from a specific country

Requires enabling the GeoIP integration and allowing the X-Geoip header in. Example to allow traffic from the US or France only.

{
  "input_headers": ["X-Geoip"],
  "extra_config": {
    "security/policies": {
      "req": {
        "policies": [
          "geoIP().Country.IsoCode in ['US','FR']"
        ]
      }
    }
  }
}

Enforce query string validation

Make sure the query string user contains a value that matches a regexp.

{
  "input_query_strings": ["user"],
  "extra_config": {
    "security/policies": {
      "req": {
        "policies": [
          "req_querystring.user.exists(u,u.matches('[0-9]+'))"
        ]
      }
    }
  }
}

Similar alternative policies:

  • hasQuerystring('user'): checks the user is not empty.
  • int(req_querystring.user[0]) > 1000: checks if the user is larger than 1000.
  • req_querystring.user[0].isAlphanumeric(): checks if the user is an alphanumeric string.

Ensure a JWT claim matches part of the URL

Suppose a JWT token contains a claim sub, and we want to make sure users can access only the endpoint that matches their profile, and is part of the URL requested.

For instance, /users/john is accessible only with valid JWT {"sub": "john"}.

{
    "endpoint": "/users/{id}",
    "input_headers":["X-Example-Claim"],
    "extra_config": {
        "security/policies":{
            "req": {
                "policies": [
                    "req_headers['X-Example-Claim'][0].lowerAscii() == req_params.Id.lowerAscii()"
                ]
            }
        },
        "auth/validator": {
            "@comment": "irrelevant config details omitted",
            "propagate_claims": [
                ["sub", "X-Example-Claim"]
            ]
        }
    }
}

Notice that the auth/validator is the first component in receiveing the request, and propagates the claim sub as the header X-Example-Claim. The header is added into the input_headers to make sure the endpoint can work with it. Finally the policy converts both the parameter {id} and the header to lower case (normalize) and checks that they have the same value.

Check that a specific cookie is set to proceed with a tracking option. For instance, there is a cookie GDPR=yes set by the user.

{
    "endpoint": "/tracking/{id}",
    "input_headers":["Cookie"],
    "extra_config": {
        "security/policies":{
            "req": {
                "policies": [
                    "getCookie('GDPR') == 'yes'"
                ],
                "error": {
                  "body": "Tracking not allowed by user",
                  "status": 403
                }
            }
        }
    }
}

The response lacks attributes

Checking that a specific response from the backend(s) contains essential data, otherwise fail.

{
    "extra_config": {
        "security/policies":{
            "resp": {
                "policies": [
                    "has(resp_data.important_attribute)"
                ],
                "error": {
                  "body": "Couldn't fetch the required data",
                  "status": 503
                }
            }
        }
    }
}
Scarf

Unresolved issues?

The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.

See all support channels