splitting proxy by app parameters

I am looking for a solution and not sure how to handle this

we want to use a single proxy to be able to serve a set of apis to users, the users would be identified by a flag on there app level e.g developer.app.userName,  each user has a limited set of apis from the suite and also gets there own app engine (target).

for example

  • User1 may have access to 3/10 apis on there engine. e.g:
  1.   /v1/user -> {user1 target}/v1/user/access
  2. {user1 target}/v1/user/refresh
  3. {user1 target}/v1/user/logout
  • User2 may have access to 1 api on there engine. e.g:
  1.  - e.g /v1/user -> {user2 target}/v1/user/getDetails

s12312731723_0-1687531394467.png

 

if I write a proxy endpoint and code all apis into the flow this then becomes a nightmare visually to see which user has access to which endpoints. and having to add if statements to determine which apis they have access to on the routing rules.

there seems to be a solution to use proxy chaining, but using multiple proxy endpoints however occurs a double quota for using the default proxy as a load balancer

e.g

Proxy Endpoint

default -> check token and append /user1 /user2 to the path and call the proxy

s12312731723_0-1687531513922.png

 

essentially we would prefer to just route from ProxyEndpoints /default to /user1 router without a double quota cost, leading to very clean documentation of the proxy in this way of having seperated flows per user

is there anything else that can do this in a clean way that I may not have considered or a way to get around the double quota issue

Thanks

1 2 147
2 REPLIES 2

we want to use a single proxy to be able to serve a set of apis to users, the users would be identified by a flag on there app level e.g developer.app.userName, each user has a limited set of apis from the suite and also gets there own app engine (target).

....

is there anything else that can do this in a clean way that I may not have considered or a way to get around the double quota issue

Yes. Well, maybe.  Depending on what you mean by "user".  There is a fundamental concept in Apigee, a central concept, that is designed specifically to support that scenario: The API Product. It is designed to support "productization of APIs" in the way you describe: some developers should have access to different "slices" of an API surface than others. 

While an API proxy is the entity on which you, as API publisher, can hang instructions on how a request should be handled - things like verify a token, use a cache, and so on.... An API Product is the unit of capability that is exposed to the consuming developer in the developer portal (or API Catalog). 

Within Apigee, you can add different subsets of one or more API Proxies, or "slices" if you like, into different API Products. For example, an app using client credentials that are authorized on Product1 could invoke GET /v1/users/{userid}, while an app buil tusing client credentials that are authorized on Product2   can invoke GET and POST on that url pattern, and also GET on /v1/users/{userid}/history .  You choose the mapping of "slices" into API Products when you create the API Products. 

After you create the products, a developer requests credentials that are authorized for a particular product. That gives the developer a client key and secret. When the app uses those credentials to obtain a token from Apigee, the resulting token will be treated by Apigee as authorized on the subset of path/verb combinations in that particular API Product.  Practically, what happens is, When the API Proxy uses VerifyAccessToken to verify a token on an incoming request, the Apigee runtime will check the verb/path combo for the current inbound request, and if that combination is not found on the API Product for which that token is authorized, Apigee will automatically  reject the call - 403 unauthorized.  The same thing happens if you use simple API Key verification instead of OAuth2 token verification within the proxy.  

You can create a large set of API products and the mappings to the specific verb/path combinations for each API Product is all up to you.  

You can also create other attributes on the API Product - for example, the upstream target URI.  And after successful verification of credentials (Token or API Key), the API Proxy can use that attribute as the target, dynamically. The default behavior in Apigee is to use a static, "hardcoded" target URI, but you can easily make it dynamic by assigning to the context variable "target.url". Simple. View a screencast covering custom attributes on API Products.

I have a separate screencast that covers some of this material, specifically how an API Product works. In this screencast, there is just a single API Product, with a very permissive verb/path combo - basically any verb on any path is allowed. But in the screencast you can see how to verb/path combinations, and you can probably figure  out for yourself how to specify a more restrictive set of combinations, and how to create multiple different products with different verb/path combinations.  Look for the relevant stuff around 12:22 into the 20 minute screencast.  Look here.

The reason I Said "Maybe" to kick this response off: if when you say "a single proxy to be able to serve a set of apis to users, " you are speaking of END USERS, that is a different story.  The problem of authorizing END USERS of an app, is different than the problem of authorizing apps themselves (or developers of those apps, if you like). Usually authorizing end users requires:

  • a user-scoped token.  Something issued via a 3-legged OAuth v2.x flow
  • A rules store, with the set of rules of the form {user, verb, resource, environment} which describes WHO can DO WHAT THING on WHAT RESOURCE, and possibly WHEN or HOW OFTEN.  That is best externalized from Apigee; a good solution is to configure the API Proxy to call into the rules engine saying "USER X is trying to DO a POST on /v1/users/xyz. Should I allow it?" and the rules engine returns a simple yes/no answer. I have called this "externalized authorization" and I produced a screencast on this topic some time ago.  View it here.

If an external rules engine is too "heavy" for your authorization purposes, you can take a half-step toward a solution by configuring your system to issue 3-legged tokens, each with a Scope, and then including a Scope configuration in the VerifyAccessToken in the API Proxy.  This requires careful design of the OAuth consent interface, which is used to issue tokens.

But all of this scope and rules engine stuff is irrelevant if by "user" you meant to imply "developer who builds apps." 

Sorry for the confusion in this case the user is actually a thirdparty integrating with our endpoints. (so a developer using our apis). we set this developer up with a internal name to identify who they are.

We then choose per third party to give them a specific set of apis e.g certain auth methods and certain actions (we don't want to give them apis they shouldn't or would not have a purpose for which allows us to reduce the testing effort per thirdparty) meanwhile all endpoints are generic and have the same routing paths (for ease of documentation purposes) e.g thirdparty1 and thirdparty2 would login with /v1/user/auth/access however it would go to a different set of servers

Will have to give the products example a try as it may work for this usecase 

Thanks