Google Apigee API Authorization
In our previous API Management post, we highlighted API authorization challenges with Azure API Management that were overcome by using SGNL. API developers using Google’s Apigee API Management platform may face similar challenges, and I’d like to show how easy it is to address them with SGNL. While the approach is similar, the integration is cloud service provider and solution specific. You can use the code from this post to protect any API with SGNL in a Google Apigee instance.
As in other integrations with API Management solutions, SGNL can help secure your Apigee-based APIs against:
- Unauthorized access from parties that should not have access to specific APIs
- Accidental sensitive data leakage
- Inadvertent elevated permissions for a principal
- Stale ambient permission sets
- API access review fatigue
- Deprecated security controls and authorization policies due to constantly changing APIs and localized ( in application silos) authorization policy
SGNL provides just-in-time access management by building a dynamic graph directory through continuous data ingestion from systems of record. Using human-readable policies, access control is enforced consistently and easily across internal and external development portals and API gateways for all API consumers (services, internal and external developers, and partners). With Google Apigee and SGNL, you can minimize sensitive data exposure and implement a fine-grained least-privileged approach to secure your APIs and deliver enterprise-scale continuous adaptive access management.
With Google Apigee and SGNL, you can minimize sensitive data exposure and implement a fine-grained least-privileged approach to secure your APIs and deliver enterprise-scale continuous adaptive access management.
Google Apigee Authorization Considerations
Enterprise-scale access management must be considered to define an overall security strategy for Google Apigee. Here are some points to consider.
- Access is more than just authentication - Review your security requirements and strategy for frontend and backend APIs. Determine the level of authorization controls, audit, logging, and centralized policy management you need. These requirements go well beyond OAuth 2.0, OpenID Connect, and mutual TLS.
- RBAC is no longer sufficient - As you may know, you can create roles within Apigee and assign them to developers and API users. This works great for coarse-grained authorization, but in most cases, you need dynamic, fine-grained permissions to prevent unauthorized access. For example, your organization may have specific partners, and each partner may have a license to use different features exposed by the same or different APIs. RBAC is not sufficient to handle such use cases, or the manual management overhead may become too heavy for RBAC to be viable. SGNL can help in this regard.
- Extend security to the backend - It is good to think about authentication and authorization from the front end to the back end. In other words, consider the impact of the front-end security controls and determine if the same requirements exist for the backend. Will you need coarse-grained authorization or fine-grained authorization, or both?
How Does Google Apigee Work
Apigee High Level Architecture
A primary component of the Google Apigee platform is the Apigee runtime. The runtime operates one or many API proxy configurations. API Requests first go through the Apigee Proxy, which applies a series of policies in pre and post-flows.
The Google Apigee platform provides a variety of policies that can be orchestrated as part of an incoming request and response. Some common policies provide functions for security, authorization (via external service callouts), request and response transformation, API usage quota management, request and response routing, and monitoring. This post focuses on service callouts for providing external fine-grained authorization decisions. The Apigee runtime performs these callouts.
Google Apigee Policies
Although Google Apigee security policies are easy to configure and customize, they mostly focus on authentication support for basic authentication (uid/password), token-based authentication (JWT, JWS), API keys, and SAML. Although there is an access control policy, this policy only implements IP-based access control. To implement real-world, fine-grained enterprise authorization scenarios without SGNL, it would be necessary to implement a variety of mediation, transformation, and extension (custom code) policies. In most cases, the extension policies require custom Java, JavaScript, or Python code to implement fine-grained authorization logic. Any changes required to follow updated policies require upgrades to such policy-as-code logic. These will most likely be cumbersome, lengthy and expensive.
Benefits of Using SGNL For Google Apigee
Here are the benefits of using SGNL with Google Apigee:
- Business Data Driven Continuous API Authorization. Any changes recorded in an organization’s business systems (e.g., ServiceNow, Salesforce, HRIS) of record are automatically and rapidly reflected in API access decisions without changing Google Apigee proxy policy.
- Simplified Google Apigee authorization policy. Google Apigee proxy policies are simplified by sending a query to SGNL with the asset, principal, and action for accessing the API endpoint. In addition, an Apigee runtime policy may also send a series of JSON key/value elements in the request to SGNL and receive an array of responses with the respective allow or deny decision.
- Real-time Audit and Comprehensive Reporting. With SGNL, all API access decisions are logged centrally with the policies that contributed to the decision to grant or deny access.
- Centralized Human Readable Policies. Human readable policies using reusable snippets enable organizations to scale policies without losing manageability.
- Consistent Authorization Decisions Across All Apps and APIs Google Apigee using SGNL, provides the same decisions consistently based on centrally managed human-readable policies.
- Contextual API Authorization Decisions Any access decision is determined considering the context of the request coming from the Google Apigee runtime. The request context received from API clients is kept intact through the Aprigee runtime, SGNL, and backend services.
How Does SGNL Work
SGNL continuously ingests data from systems of record to a central graph directory via resilient and performant connectors. This data includes identity data, such as users and groups, and any relevant data required to define access policies, such as ITSM cases or customers from CRM.
In this post, we use ServiceNow and Okta. Okta is our Identity Provider system of record and ServiceNow provides the assigned and active case for the user.
An example data source in SGNL (ServiceNow)
Once a data source is set up, administrators can quickly author and manage human-readable policies based on the configured data sources for granting or denying access to applications, APIs, and sensitive data. By implementing a centralized approach, SGNL provides consistency in centralized policy management, audit logging, and reporting across all assets an organization desires to protect (including APIs). These capabilities (and more) comprise SGNL’s enterprise-ready just-in-time access management platform.
Instead of configuring and developing complex policies in Google Apigee to evaluate access, you simply use SGNL to select policy snippets from the user interface and graphically build a human-readable policy. The SGNL Google Apigee policies ensure that any API call to the Apigee proxy endpoint is evaluated against the latest data ingested from systems of record and the policies defined in SGNL.
Example of a real policy that allows write access to a mock file sharing API.
This human-readable policy allows access to the mock file-sharing service for API clients acting on behalf of engineering principals. When the API client makes a request through the Google Apigee runtime, the request is authorized by the SGNL access service. The authorization result is then centrally monitored and audited.
Google Apigee Runtime and SGNL Integration
The integration between Google Apigee and SGNL is based on the Apigee Proxy pre-flow policies. Pre-flow policies allow you to execute code before any request is sent to the target backend API endpoint. Pre-flow policies are useful for authenticating and authorizing clients before the API proxy takes any other action. The proxy pre-flow policies may be configured for any Apigee proxy endpoint.
Example of SGNL Apigee Proxy pre-flow policies.
See policy details in the Google Apigee Proxy Policies section.
SGNL and Google Apigee Architecture
The integration between SGNL and Apigee is straightforward. In order to integrate into SGNL, an Apigee administrator simply defines and configures the associated policies and flow for calling the SGNL access service API. This is depicted in the diagram below.
Mock File Sharing API
This post uses a mock API from httpbin.org to simulate posting a JSON payload to an endpoint. Httpbin.org is an open-source mock REST API for helping to test API clients. This endpoint represents a mock file-sharing service API endpoint. This solution demonstrates the ability to use the Google Apigee proxy for front-ending a REST API secured by the combination of the Apigee Proxy and SGNL’s just-in-time authorization. This mock endpoint accepts an HTTP POST request from the Google Apigee proxy and returns an example JSON response. The request is not sent to the backend mock service if the request is denied by the SGNL Access Service based on configured Google Apigee proxy policies.
SGNL Apigee Proxy Pre-Flow Policies
The Google Apigee Proxy policies below show how to construct an SGNL authorization request for an incoming HTTP POST request from an API client. This sample implementation takes the “principal” key/value pair in the incoming JSON body and the HTTP Authorization header, which contains the bearer token for authenticating to the SGNL Access Service.
Flow Steps
Apigee proxy runtime pre-flow policy execution sequence diagram.
The diagram above depicts the execution flow starting from the API client, through the Apigee proxy, and finally back to the Apigee’s proxy runtime response back to the API client. The Apigee runtime will execute the proxy pre-flows in order as defined by the Apigee developer or engineer. The steps are:
- The API client makes a request to the Apigee proxy endpoint which starts the execution of the pre-flow policies.
- The Apigee proxy runtime executes the EV-Authorization policy.
- The Apigee proxy runtime executes the EV-Principal policy.
- The Application proxy runtime executes the AM-SGNL policy.
- (A) The Application proxy runtime executes the SC-SGNL policy which makes a call to the SGNL Access Service. (B) The SGNL Access Service responds with a JSON document with the authorization decisions.
- The Apigee proxy runtime executes the EV-SGNL-Response policy.
- The Apigee proxy runtime executes the RF-SGNL-Response policy.
- (A) If the SGNL decision is allow the Apigee proxy runtime will make an http(s) request to the API server and receive the response. (B) The Apigee proxy runtime will then send a HTTP 200 response to the API Client along with the requested resource. (C) If the SGNL decision is deny, then the Apigee proxy runtime will send the API client an HTTP 403 Forbidden response.
Below are the policy XML and expression details.
EV-Authorization Policy
An extract variables policy extracts content from a request or response. The extracted value is set as a variable that may be used by other Apigee policies in the request and response flow. The extract variable (EV) EV-Authorization policy extracts the access token sent by the API consumer. This access token is used to authenticate to the SGNL Access Service.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables continueOnError="false" enabled="true" name="EV-Authorization">
<DisplayName>EV-Authorization</DisplayName>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<Header name="Authorization">
<!-- No space between "Bearer" and the accessToken variable -->
<Pattern ignoreCase="true">Bearer {accessToken}</Pattern>
</Header>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<VariablePrefix>sgnl</VariablePrefix>
</ExtractVariables>
EV-Principal
The EV-Principal policy extracts the principal id from the incoming POST request. This principal id is used in a subsequent “assign” message policy for constructing the request to the SGNL Access Service.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables continueOnError="false" enabled="true" name="EV-Principal">
<DisplayName>EV-Principal</DisplayName>
<Source clearPayload="false">request</Source>
<JSONPayload>
<Variable name="principal" type="string">
<JSONPath>$.principal.id</JSONPath>
</Variable>
</JSONPayload>
<VariablePrefix>sgnl</VariablePrefix>
</ExtractVariables>
AM-SGNL
This policy constructs the request for the SGNL Access Service. The policy references the SGNL access token and principal variables set by the previous extract variable policies.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-SGNL">
<AssignTo createNew="true" type="request">sgnl.authz</AssignTo>
<DisplayName>AM-SGNL</DisplayName>
<Set>
<Verb>POST</Verb>
<Headers>
<Header name="Authorization">Bearer {sgnl.accessToken}</Header>
</Headers>
<Payload contentType="application/json">
{
"principal": {
"id": "{sgnl.principal}"
},
"queries": [{
"assetId": "File Sharing",
"action": "Write"
}]
}
</Payload>
</Set>
</AssignMessage>
SC-SGNL
This is the service callout policy for calling the SGNL Access Service. The SGNL authorization response will be stored in the sgnlResponse variable.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout continueOnError="false" enabled="true" name="SC-SGNL">
<DisplayName>SC-SGNL</DisplayName>
<Properties/>
<Request clearPayload="true" variable="sgnl.authz">
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<Response>sgnlResponse</Response>
<HTTPTargetConnection>
<Properties/>
<URL>{{Replace with the SGNL Access Service URL}}</URL>
</HTTPTargetConnection>
</ServiceCallout>
EV-SGNL-Response
This policy extracts the SGNL Access Service response and decision. This policy stores the allow or deny decision in the sgnl.decision variable. This variable is then used in the conditional raise fault policy to determine whether or not to allow the request to proceed or to halt the request, raise a fault, and return a 403 access denied message to the API client.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables continueOnError="false" enabled="true" name="EV-SGNL-Response">
<DisplayName>EV-SGNL-Response</DisplayName>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<Source clearPayload="false">sgnlResponse</Source>
<JSONPayload>
<Variable name="decision" type="string">
<JSONPath>$.decisions[0].decision</JSONPath>
</Variable>
</JSONPayload>
<VariablePrefix>sgnl</VariablePrefix>
</ExtractVariables>
RF-SGNL-Response
This policy raises a fault and sets an HTTP status code of 403. This is a conditional fault that is raised if the sgnl.decision = “Deny”.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault continueOnError="false" enabled="true" name="RF-SGNL-RESPONSE">
<DisplayName>RF-SGNL-RESPONSE</DisplayName>
<FaultResponse>
<Set>
<Payload contentType="application/json">\{"Forbidden": \{"message":"SGNL Access Service Response - Not Authorized", "details":"You are not authorized to access this API.</Payload>
<StatusCode>403</StatusCode>
<ReasonPhrase>Access Forbidden</ReasonPhrase>
</Set>
</FaultResponse>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>
SGNL Access Service Request Context
The following example contains a JSON document sent to the Google Apigee proxy endpoint by the API client. This principal is inserted into the JSON body and posted to the SGNL Access Service to evaluate the just-in-time access policy.
{
"principal": {
"id": "adela.cervantsz@sgnl.ai"
}
}
Conclusion
Using this SGNL and Google Apigee integration, organizations can reduce risk; developers can reduce authorization logic complexity and leverage a centralized access management policy platform for making complex just-in-time authorization decisions.