Protecting APIs on Apigee Edge Gateway

Instructions on how to discover, integrate and protect your APIs deployed behind the Apigee Edge gateway.

Prerequisites

Entitlements

Apigee Edge Authorizer has two features which require access to Apigee Edge API.

  • API discovery

    API discovery works by grouping and converting a list of Apigee Edge products into a format required by ACP. The product list is obtained from the Apigee Edge API. To make it work, the configured user must have access to the product list.

  • Shared Flow installation

    Shared flow installation works by uploading a compressed package to Apigee Edge. If the shared flow already exist, a new revision is created. To make it work, the configured user must have a built-in Organization Administrator role.

Apigee Edge and SAML

Apigee Edge Authorizer, with its API discovery capabilities and a possibility to install a shared flow within your Apigee Gateway instance, exists with your Apigee Edge instance in a machine to machine environment. The authorizer does the automation for you. Because of that, when SAML is enabled for your Apigee Edge Gateway, it is not possible to use traditional password flow for SAML users to obtain OAuth2 access and refresh tokens.

To make it possible for you to authenticate your machine (in this case, the Apigee Edge Authorizer) when using SAML, Apigee Edge introduces the concept of machine users. Such users can obtain OAuth2 tokens for your authorizer without a need to specify a passcode and they are stored within your Edge datastore, not your SAML identity provider. You can limit access for such users, but make sure that the user you create for authorizer’s needs has access to the product list and has the Organization Administrator role built-in. Credentials of your machine user are later on provided in your authorizer’s docker-compose.yaml file.

Learn more

You can learn more about machine users and how to create them in Using SAML with automated tasks Apigee Edge documentation

Create Apigee Edge gateway

  1. Log in to your ACP tenant.

  2. Open your authorization server (workspace).

  3. Go to APIs -> Gateways.

  4. Select Add Gateway. A list of available gateways appears.

  5. Select Apigee Edge. Provide the name and description.

  6. Optionally, enable the Create and bind services automatically check box.

    Tip

    When enabled, all services protected by your Apigee Edge instance are discovered and added to the ACP service list automatically when the Apigee authorizer is connected to ACP. Otherwise, you need to add them manually.

  7. Follow the Quick Start instruction. Download the package from your tenant and check the Integrate ACP and Apigee Edge instructions.

Integrate ACP and Apigee Edge Authorizer

  1. Unzip the package and open the docker-compose.yaml file.

  2. Edit the following parameters to match your Apigee Edge instance:

    • APIGEE.APIGEE_EDGE.USERNAME=username - replace with your username

    • APIGEE.APIGEE_EDGE.PASSWORD=password - replace with your password

    • APIGEE.APIGEE_EDGE.ORGANIZATION_ID=org-id - replace with your organization ID

    version: '3'
    
    services:
    apigee-authorizer:
        container_name: apigee-edge-authorizer
        image: docker.cloudentity.io/apigee-authorizer:1.13.0
        env_file: .authorizer_env
        environment:
        - APIGEE.APIGEE_PRODUCT=ApigeeEdge
        - APIGEE.ACP_RELOAD_INTERVAL=5s # for demo purposes only, increase for production!
        - APIGEE.APIGEE_EDGE.USERNAME=username
        - APIGEE.APIGEE_EDGE.PASSWORD=password
        - APIGEE.APIGEE_EDGE.ORGANIZATION_ID=org-id
        ports:
        - 8442:8442
        restart: on-failure
    

    Tip

    The APIGEE.ACP_RELOAD_INTERVAL configuration parameter defines how often ACP tries to discover APIs on your gateway.

    Save your changes when done.

  3. Run the docker-compose run apigee-authorizer install command in your terminal.

    Result

    When you run the command, a shared Authorizer flow is created automatically for you in your Apigee Edge instance. The shared flow consists of two policies:

    • A JavaScript Cloudentity Authorizer Policy that is responsible for communicating with the Apigee Edge Authorizer and for blocking/allowing the request depending on the Authorizers decision.

    • An XML Raise Authorization Error policy that is responsible for delivering the error status as the response to the unauthorized call to the protected API.

  4. Run docker-compose up. After a short while, Apigee Edge authorizer should be running.

    docker-compose up
    Creating apigee-edge-authorizer ... done
    Attaching to apigee-edge-authorizer
    apigee-edge-authorizer | time="2021-08-27T13:37:53Z" level=info msg="starting apigee authorizer" commit=289e388 version=1.13.0
    apigee-edge-authorizer | time="2021-08-27T13:37:54Z" level=info msg="apigee-authorizer listening on https://localhost:8442"
    
  5. Go to APIs > Gateways > your_gateway > APIs. You should see a familiar list of services deployed using Apigee Edge.

    Note

    If you do not see a list of services deployed on Apigee Edge, make sure that at least one API Product is defined in your Apigee Edge organization with a connected API proxy.

    Note

    If you need to limit the count of discovered APIs, you can configure product_name_regexp or environment_name_regexp. Setting it up will limit discovered APIs to matching names.

  6. Select Connect > Create new service on a protected API from the list to add it to a list of ACP-protected services. Give this new ACP service a name when prompted.

    Note

    If you selected the Create and bind services automatically option when creating the gateway, your services are bound already.

    Result

    Your Apigee Edge-protected API is now on the list of ACP-protected services.

  7. Deploy your Apigee Edge authorizer so that it is available publicly.

    Tip

    So far, you have only deployed your Apigee Edge authorizer locally using the Docker image provided by Cloudentity. You must expose it publicly as it is needed later on for the integration to work. For testing purposes, you can use tools like, for example, ngrok that expose local servers behind NATs and firewalls to public internet over secure channels.

Apigee Edge Authorizer Configuration

For Apigee Edge Authorizer, it is possible to adjust its configuration. Below you can see an example of how the reference.yaml file looks like for the Apigee Edge Authorizer in the 1.15 ACP release.

server:
    port: 8442
    dangerous_disable_tls: false
    certificate:
        password: "" # key passphrase
        cert_path: "" # path to the certificate PEM file
        key_path: "" # path to the key PEM file
        cert: "" # base64 encoded cert PEM
        key: "" # base64 encoded key PEM
        generated_key_type: ecdsa # type for generated key if cert and key are not provided (rsa or ecda)
apigee:
    acp_reload_interval: 1m0s
    acp_reload_timeout: 30s
    acp_issuer_url: https://{tid}.us.authz.cloudentity.io/{tid}/system
    acp_client_id: {CLIENT_ID}
    acp_client_secret: {CLIENT_SECRET}
    disable_analytics: false
    disable_discovery: false
    do_not_fail_on_non_matching_requests: false
    analytics:
        probability: 1
        batchinterval: 1s
        batchlimit: 100
        limit: 5
        timeout: 5s
        workers: 8
    client:
        timeout: 10s # http client timeout
        retry_wait_min: 0s # minimum time to wait between retries
        retry_wait_max: 0s # maximum time to wait between retries
        retry_max: 0 # maximum number of retries
        root_ca: "" # root ca that this client should trust (defaults to system root ca)
        insecure_skip_verify: false # disable cert verification
        disable_follow_redirects: false # disable follow redirects
        disable_retry: true # disable retry
    apigee_product: ApigeeX
    apigee_edge:
        username: ""
        password: ""
        organization_id: ""
        base_url: https://api.enterprise.apigee.com
        token_url: https://login.apigee.com/oauth/token
        use_token: true
        debug: false
    api_discovery_filters:
        product_name_regexp: ""
        environment_name_regexp: ""
    cache_ttl: 10s
    cache_max_size: 100
shared_flow_path: data

You can generate a reference configuration for your Apigee Edge Authorizer using the docker-compose run apigee-authorizer reference command.

You can use the reference configuration as a basis for your customization. You can omit settings for which the default configuration is satisfactory, specifying only the required values, which are the client ID, client secret, and issuer URL parameters like it is shown below:

   environment:
     - APIGEE.APIGEE_PRODUCT=ApigeeEdge
     - APIGEE.ACP_RELOAD_INTERVAL=5s
     - APIGEE.APIGEE_EDGE.USERNAME=username
     - APIGEE.APIGEE_EDGE.PASSWORD=password
     - APIGEE.APIGEE_EDGE.ORGANIZATION_ID=org-id

Tip

Note that nested YAML settings can be accessed by joining uppercased names with periods, as shown in the example above, where the APIGEE.APIGEE_EDGE.PASSWORD=password parameter is set.

To run the standalone authorizer with a configuration file, you need to perform the following steps:

  1. Add a volumes parameter to your docker-compose.yml file:

    Example

    volumes:
    - /Path/To/Your/Authorizer/apigee-edge-authorizer:/apigee
    

    volumes attaches the defined catalog (/Path/To/Your/Authorizer/apigee-edge-authorizer) to your authorizer’s docker image and maps it to a catalog that, from now on, exists on your docker image (apigee). This is the place where your configuration is stored on your authorizer’s docker deployment.

  2. Use the --config option to specify the YAML file with your configuration. For example, assuming that you have created a apigee_edge_config.yaml file in your current directory, your docker run command would look like the following:

    docker-compose run apigee-authorizer --config=/apigee/apigee_edge_config.yaml
    

Client authentication

By default, the Apigee Edge Authorizer uses OAuth2 access tokens to authenticate itself to your Apigee Edge instance. It is defined using the use_token: true setting in the Apigee Edge Authorizer’s configuration. If you wish to use Basic Authentication, set it to false.

You can do this by, for example, by providing the APIGEE.APIGEE_EDGE.USE_TOKEN=false environment variable in the docker-compose.yml file responsible for your authorizer’s docker deployment.

Configure Apigee Edge Gateway

With Apigee Edge Gateway, you can define policies that are an Edge components that you can attach to different points in the message flow through your API proxies. Such policies can transform the message format, call remote services, and more. To protect your APIs, elevate the integration between ACP and the Apigee Edge platform. Doing so allows you to enforce access control using Apigee Edge policies and ACP authorization policies.

  1. In your Apigee Edge API Proxy settings, go to the DEVELOP tab.

  2. In the Navigator > Policies add a policy of the Flow Callout type.

    Tip

    You can find the Flow Callout policy type under the EXTENSTION tree node.

  3. Provide a name and a display name for your policy.

  4. As a shared flow, use the Authorizer shared flow.

    Result

    Your policy is created. It is defined with the following XML:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <FlowCallout async="false" continueOnError="false" enabled="true" name="Flow-Callout">
      <DisplayName>Flow Callout</DisplayName>
      <FaultRules/>
      <Properties/>
      <SharedFlowBundle>Authorizer</SharedFlowBundle>
    </FlowCallout>
    
  5. Configure your policy so that it points to your Apigee Edge authorizer’s /authorize endpoint that you have deployed in the seventh step of the Integrate ACP and Apigee Edge section

    Example

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <FlowCallout async="false" continueOnError="false" enabled="true" name="microPerimeter">
       <DisplayName>microPerimeter</DisplayName>
       <FaultRules/>
       <Properties/>
       <Parameters>
           <Parameter name="authorizer_url">https://yourAuthorizerURL/authorize</Parameter>
           <Parameter name="proxy_body">false</Parameter>
       </Parameters>
       <SharedFlowBundle>Authorizer</SharedFlowBundle>
    </FlowCallout>
    

    proxy_body parameter

    If the proxy_body parameter is set to true, the shared flow policy proxies the request body to the authorizer and then to the policies. Thanks to that it is possible to create policies that reject requests based on the request body. The request body must be in the JSON format.

    The proxy_body option is disabled by default to make it possible to use bigger-sized request bodies, for example, for image uploads.

  6. Add your new policy as a <step> element to your Proxy Endpoints PreFlows.

    Example

    <PreFlow name="PreFlow">
       <Request>
           <Step>
               <Name>microPerimeter</Name>
           </Step>
       </Request>
       <Response/>
    </PreFlow>
    

    Note

    You have to add your new policy to your Proxy Endpoints PreFlows, as the authorization must take place before the request reaches to target endpoint.

  7. Select Save.

Apply a sample policy

  1. In ACP, create a policy.

  2. Select APIs from the left sidebar and go to the AUTHORIZATION tab.

  3. Select a service protected by the Apigee Edge authorizer and any API with authorization status Unrestricted.

  4. In the Edit API popup window, select Policy from the dropdown list and click Update to proceed.

Result

You have successfully assigned a policy to your API.

Test integration

To test if your integration was successfull and that your APIs are protected, you can, for example, create a simple Cloudentity or REGO policy that will always pass. Call your protected endpoint and check if the response contains the successfull status. If yes, change your policy so that it blocks APIs. The next request to your protected enpoint should end with the unauthorized access error.

Troubleshooting

HTTP 403 status codes

  • Check your Apigee username, password and organization id
  • Check if the configured user exists in a given Apigee organisation
  • Check if the user has an access necessary to perform a given operation

Discovery command

To quickly check if Apigee Edge credentials are configured correctly, run a single API discovery pass:

docker-compose run apigee-authorizer discovery

The expected result is a log with a list of APIs required by ACP.

Debug flag

Apigee Edge authorizer is able to log all inbound and outbound traffic from the Apigee Edge API. These logs can be useful to debug connectivity problems. To enable it, the debug flag must be set to true. The flag can be set by using an environment variable or passed directly via a configuration file. The debug flag works with the start (default) and discovery commands.

APIGEE.APIGEE_EDGE.DEBUG=true

Warning

The debug logs contain sensitive information such as credentials.