Send Docs Feedback

Access Control policy

What

The Access Control policy lets you allow or deny access to your APIs by specific IP addresses.

Where

This policy can be attached in the following locations.

ProxyEndpoint TargetEndpoint
    PreFlow Flow PostFlow PreFlow Flow PostFlow    
Request    
    Response
    PostFlow Flow PreFlow PostFlow Flow PreFlow    

While you can attach this policy anywhere in the API proxy flow, you'll most likely want to check IP addresses at the beginning of the flow ( Request / ProxyEndpoint / PreFlow), even before authentication or quota checking.

Samples

The mask values in the following IPv4 samples identify which of the four octets (8, 16, 24, 32 bits) the match rule considers when allowing or denying access. The default value is 32. See the mask attribute in the Element reference for more information.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="ALLOW">
    <MatchRule action="DENY">
      <SourceAddress mask="32">10.10.10.10</SourceAddress>
    </MatchRule>
  </IPRules>
</AccessControl>

Deny all requests from client address: 10.10.10.10

Allow requests from any other client address.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="ALLOW">
    <MatchRule action="DENY">
      <SourceAddress mask="24">10.10.10.10</SourceAddress>
    </MatchRule>
    </IPRules>
</AccessControl>

Deny all requests from client address: 10.10.10.*

Allow requests from any other client address.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="ALLOW">
    <MatchRule action="DENY">
       <SourceAddress mask="16">10.10.10.10</SourceAddress>
    </MatchRule>
  </IPRules>
</AccessControl>

Deny all requests from client address: 10.10.*.*

Allow requests from any other client address.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="ALLOW">
    <MatchRule action="ALLOW">
      <SourceAddress mask="32">10.10.10.20</SourceAddress>
    </MatchRule>
    <MatchRule action="DENY">
      <SourceAddress mask="24">10.10.10.20</SourceAddress>
    </MatchRule>
  </IPRules>
</AccessControl>

Deny all requests from client address: 10.10.10.*, but allow 10.10.10.20.

Allow requests from any other client address.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="DENY">
    <MatchRule action="ALLOW">
      <SourceAddress mask="16">10.10.10.10</SourceAddress>
    </MatchRule>
  </IPRules>
</AccessControl>

Allow all requests from address: 10.10.*.*

Deny requests from any other client address.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="DENY">
    <MatchRule action="ALLOW">
      <SourceAddress mask="24">10.10.20.0</SourceAddress>
      <SourceAddress mask="24">10.10.30.0</SourceAddress>
      <SourceAddress mask="24">10.10.40.0</SourceAddress>
     </MatchRule>
  </IPRules>
</AccessControl>

Whitelist (allow requests from) client addresses: 10.10.20.* 10.10.30.* 10.10.40.*

Deny all other addresses.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="ALLOW">
    <MatchRule action="DENY">
      <SourceAddress mask="24">10.10.20.0</SourceAddress>
      <SourceAddress mask="24">10.10.30.0</SourceAddress>
      <SourceAddress mask="24">10.10.40.0</SourceAddress>
    </MatchRule>
  </IPRules>
</AccessControl>

Blacklist (deny requests from) client addresses: 10.10.20.* 10.10.30.* 10.10.40.*

Allow all other addresses.

<AccessControl name="ACL">
  <IPRules noRuleMatchAction="DENY">
    <MatchRule action="DENY">
      <SourceAddress mask="24">10.10.0.0</SourceAddress>
      <SourceAddress mask="24">10.20.0.0</SourceAddress>
      <SourceAddress mask="24">10.30.0.0</SourceAddress>
    </MatchRule>
    <MatchRule action="ALLOW">
      <SourceAddress mask="16">10.10.0.0</SourceAddress>
      <SourceAddress mask="16">10.20.0.0</SourceAddress>
      <SourceAddress mask="16">10.30.0.0</SourceAddress>
    </MatchRule>
  </IPRules>
</AccessControl>

Whitelist: 10.10.*.* 10.20.*.* 10.30.*.*

Blacklist a subset of the whitelist: 10.10.0.* 10.20.0.* 10.30.0.*


Usage notes

In addition to protecting your APIs against malicious IPs, the Access Control policy also gives you control over legitimate IP access. For example, if you only want computers under the control of your enterprise to access the APIs exposed in your test environment, you can allow (or whitelist) the IP address range for your internal network. Developers working from home can access these APIs using VPN.

If you block a specific address, the computer using that IP address can still direct requests to your API through a proxy. It is also possible to spoof (falsify) the IP address of a request, so the request appears to come from a reputable source.

The configuration and execution of an Access Control policy includes the following tasks and behaviors:

  • Define a set of match rules with one of two actions (ALLOW or DENY) associated with each.
  • For each match rule, specify the IP address (SourceAddress element).
    • Configure a mask for each IP address. You allow or deny access based on a mask value on the IP address. See About IP masking with CIDR notation.
    • If the X-FORWARDED-FOR header is present in the request address, then the header value is considered the source address. If there are multiple addresses in the header, use the <ValidateBasedOn> element to control which are evaluated.
  • Specify the order in which the rules are tested.
  • All the match rules are executed in the given order. When a rules matches, the corresponding action is executed and following match rules are skipped.
    • If the same rule is configured with both ALLOW and DENY actions, the rule that is defined first in the order is triggered and the subsequent rule (with the other action) is skipped.

About IP masking with CIDR notation

CIDR notation (Classless Inter-Domain Routing) is a way of indicating a range of IP addresses through masking. It applies to both IPv4 and IPv6. Here's how it works. We'll use IPv4 in our examples for simplicity.

IP addresses are groups of numbers separated by periods. Each number is a specific number of bits (8 for IPv4 and 16 for IPv6). The IPv4 address 10.20.30.40 looks like this in binary:

00001010 . 00010100 . 00011110 . 00101000

That's 4 groups of 8 bits, or 32 total bits. With CIDR, you can indicate a range by adding a /number (1-32) to the IP address, like this:

10.20.30.40/16

In this case, the 16 is the number you would use for the mask attribute value in this policy.

This notation means, "Keep the first 16 bits exactly as is, the remaining bits can be anything." For example:

Notice that the mask happens at the end of group two. This makes things nice and tidy, in essence creating a mask like this: 10.20.*.*. In most cases, using multiples of 8 (IPv4) and 16 (IPv6) will give you the masking level you want:

IPv4: 8, 16, 24, 32

IPv6: 16, 32, 48, 64, 80, 96, 112, 128

However, you can user other numbers for finer-grained control, which involves a little binary calculation. Here's an example using a mask of 22:

Here it gets a litle tricky: keep the first 22 bits and allow anything in the rest—per group. In group 3, keep the first 6 bits, the last two can vary. That's four possible combinations (00, 01, 10, 11), leaving the following possible numbers in group 3: 28, 29, 30, and 31. Since none of group 4 is affected by the mask, values can be anything from 0 to 255.

Element reference

The element reference describes the elements and attributes of the Access Control policy.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessControl async="false" continueOnError="false" enabled="true" name="Access-Control-1">
    <DisplayName>Access Control 1</DisplayName>
    <IPRules noRuleMatchAction="ALLOW">
        <MatchRule action="ALLOW">
            <SourceAddress mask="32">10.10.10.20</SourceAddress>
        </MatchRule>
        <MatchRule action="DENY">
            <SourceAddress mask="24">10.10.10.20</SourceAddress>
        </MatchRule>
    </IPRules>
    <ValidateBasedOn>X_FORWARDED_FOR_ALL_IP</ValidateBasedOn>
</AccessControl>

<AccessControl> attributes

<AccessControl async="false" continueOnError="false" enabled="true" name="Access-Control-1"> 

The following attributes are common to all policy parent elements.

Attribute Description Default Presence
name

The internal name of the policy. Characters you can use in the name are restricted to: A-Z0-9._\-$ %. However, the Edge management UI enforces additional restrictions, such as automatically removing characters that are not alphanumeric.

Optionally, use the <DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

N/A Required
continueOnError

Set to false to return an error when a policy fails. This is expected behavior for most policies.

Set to true to have flow execution continue even after a policy fails.

false Optional
enabled

Set to true to enforce the policy.

Set to false to "turn off" the policy. The policy will not be enforced even if it remains attached to a flow.

true Optional
async

Note: This attribute does not make the policy execute asynchronously.

When set to true, policy execution is offloaded to a different thread, leaving the main thread free to handle additional requests. When the offline processing is complete, the main thread comes back and finishes handling the message flow. In some cases, setting async to true improves API proxy performance. However, overusing async can hurt performance with too much thread switching.

To use asynchronous behavior in API proxies, see JavaScript callouts.

false Optional

<DisplayName> element

Use in addition to the name attribute to label the policy in the management UI proxy editor with a different, natural-language name.

<DisplayName>Policy Display Name</DisplayName>
Default:

N/A

If you omit this element, the the value of the policy's name attribute is used.

Presence: Optional
Type: String

 

<IPRules> element

The parent element containing the rules that allow or deny IP addresses. The noRuleMatchAction attribute lets you define how to handle any IP addresses that aren't covered by your matching rules.

<IPRules noRuleMatchAction="ALLOW">
Default N/A
Presence Optional
Type N/A

Attributes

Attribute Description Type Default Presence
noRuleMatchAction
The action to take (allow or deny access) if the match rule specified is not resolved (unmatched).
Valid value: ALLOW or DENY
 
String ALLOW Required

<IPRules>/<MatchRule> element

The action to take (allow or deny access) if the IP address matches the SourceAddress(es) you define.

<IPRules noRuleMatchAction="ALLOW">
    <MatchRule action="ALLOW">
        <SourceAddress mask="32">10.10.10.20</SourceAddress>
    </MatchRule>
    <MatchRule action="DENY">
        <SourceAddress mask="24">10.10.10.20</SourceAddress>
    </MatchRule>
</IPRules>
Default N/A
Presence Optional
Type N/A

Attributes

Attribute Description Type Default Presence
action

The action to take (allow or deny access) if the match rule specified is not resolved (unmatched).

Valid value: ALLOW or DENY

String ALLOW Required

<IPRules>/<MatchRule>/<SourceAddress> element

The IP address range of a client.

Valid value: Valid IP address (dotted decimal notation). For wildcard behavior, use the mask attribute.

<IPRules noRuleMatchAction="ALLOW">
    <MatchRule action="ALLOW">
        <SourceAddress mask="32">10.10.10.20</SourceAddress>
    </MatchRule>
    <MatchRule action="DENY">
        <SourceAddress mask="24">10.10.10.20</SourceAddress>
    </MatchRule>
</IPRules>
Default N/A
Presence Optional
Type String

Attributes

Attribute Description Type Default Presence
mask

The mask attribute is a way to indicate the range of IP addresses to allow or deny. Mask is the equivalent of using CIDR notation (Classless Inter-Domain Routing). For example:

<SourceAddress mask="24">192.168.100.0</SourceAddress>

is equivalent to the following CIDR notation:

192.168.100.0/24

Valid values:

IPv4: 1-32

IPv6: 1-128

A value of zero (0) is valid only for IP 0.0.0.0, hence impractical.

For more guidance, see About IP masking with CIDR notation.

Integer N/A Required

<ValidateBasedOn> element

If the X-FORWARDED-FOR HTTP header is present in the request address, then the header value is considered the source address.

If there are multiple IP addresses you want to check in the X-FORWARDED-FOR header—for example, if the header contains the client IP address along with the IP addresses of proxies through which the request was sent (client, proxy1, proxy2)—use this ValidateBasedOn element to control which of the IP addresses are checked.

You must enable this feature, which involves setting the feature.enableMultipleXForwardCheckForACL property in your organization. To enable it in the cloud, contact Apigee Support. To enable it on-premises in Edge for Private Cloud, see the API call below.

The value you enter in this element lets you determine whether to check all IP addresses in the header (default), only the first IP address, or only the last IP address.

<ValidateBasedOn>X_FORWARDED_FOR_ALL_IP</ValidateBasedOn>
Default X_FORWARDED_FOR_ALL_IP
Presence Required
Type String
Valid values
  • X_FORWARDED_FOR_ALL_IP (default)
  • X_FORWARDED_FOR_FIRST_IP
  • X_FORWARDED_FOR_LAST_IP

Apigee Edge for Private Cloud customers can set the feature.enableMultipleXForwardCheckForACL property with the following API call:

curl -u email:password -X POST -H "Content-type:application/xml" http://host:8080/v1/o/myorg -d \
"<Organization type="trial" name="MyOrganization">
    <DisplayName>MyOrganization</DisplayName>
    <Environments/>
    <Properties>
        <Property name="feature.enableMultipleXForwardCheckForACL">true</Property>
    </Properties>
</Organization>"

See our GitHub repository samples for the most recent schemas.

Error codes

The default format for error codes returned by Policies is:

{
  "code" : " {ErrorCode} ",
  "message" : " {Error message} ",
  "contexts" : [ ]
}

The AccessControl Policy type returns the following error codes:

Error Code Message
accesscontrol.ClientIpExtractionFailed Client IP extraction failed
IPDeniedAccess Access Denied for client ip : {0}
InvalidIPAddress {0} is not a valid IP address
InvalidIPv4Address {0} is not a valid IPv4 address
InvalidIPv6Address {0} is not a valid IPv6 address
InvalidRulePattern Invalid rule pattern {0}

 

Help or comments?

  • If something's not working: Ask the Apigee Community or see Apigee Support.
  • If something's wrong with the docs: Click Send Docs Feedback on this page.
    (Incorrect? Unclear? Broken link? Typo?)