Allow API proxy access only from Browser

We want our proxies to be accessed only via browser. Is there any way to achieve this ?

Developer should not be able to access that proxy via other means like POSTMAN or SOAP UI

0 9 531
9 REPLIES 9

Nope, I cannot think of a way to do that reliably.

The only thing that distinguishes a request that originates from a browser, from one that originates from SOAP-UI or Postman, is the user-agent header. But that can be spoofed.

What's the reason for your desire to restrict in this way?

my first idea was mtls, but you can do that in postman\soap also

Kerberos? Smart card?

Yes, to allow only "a designated client" like a specific browser to invoke an API, you'd need to have some sort of authentication of that client. That means a cert (maybe stored on a smartcard etc.).

But even that doesn't prevent other clients from using the same cert. For a motivated developer, they will be able to access the cert. (Physical security is the root of all security).

Hi Dino

We are exposing compensation data from our source system using apigee proxies.

This compensation data should be available to person who has logged in. This consumer is browser based application.

One way is that we can restrict this data by passing USERNAME in header and validating it in apigee. By this we can ensure that user is same as logged in person.

But for now even the developers on consumer side should NOT have access to the data of other employees. They can easily use POSTMAN and pass USERNAME in header and get this data.

So what we were thinking, is there any way to restrict this data. We want to show only when request has come from browser. If you think there is a better way then please let us know.

But for now even the developers on consumer side should NOT have access to the data of other employees. They can easily use POSTMAN and pass USERNAME in header and get this data.

I understand. ok in that case, you will need to introduce some way of allowing Apigee to verify that the user who is requesting the information

  1. is authentic
  2. is the same user as is being requested in the query. Or, more generally, is a user who is authorized to see the information in the query.

The way to allow Apigee to accomplish #1 is to either let Apigee inspect the session, or configure Apigee to trust the holder of the session. It sounds like you're building a web app. If the user logs in to the webapp, then there's a session, which gets established upon user authentication. There's a cookie or a thing that the browser passes to the webapp, and the webapp then inspects that cookie to determine "is this user authentic?"

One possibility is that the session itself is an ID Token issued by an OpenID Connect server (like Okta, Auth0, or Ping, etc). This ID Token will be a JWT, signed using the private key of the Identity Provider. The webapp client (browser with JS logic) holds this ID token and can transmit it to the upstream systems, like APigee. Apigee can then verify the signature on the ID token. This verifies that the user is authentic. (Well, not quite. It verifies that the TOKEN is authentic. We can be assured that the user is authentic if we're sure the user didn't give away his/her token. Or if the token didn't leak in some other way.)

Ok, I said that's one possibility. Not the only possibility. The JWT makes it easy because JWT can be verified by "anybody" , and in this case Apigee is that "anybody." In the more general case the browser-based webapp has a cookie that it replays to the webapp server. This cookie is opaque. The webapp server knows how to decrypt or otherwise dereference the cookie. Each time the browser makes a request, it sends the cookie, and the webapp server inspects it to check "is the user logged in" and "is this login not yet expired" etc.

You can send the same information to your Apigee proxy in a web request. The trick here is that if the cookie is opaque, your Apigee proxy won't know how to dereference it, to make sense of it. Therefore you have got to allow Apigee to send that session to the webapp server to "introspect" it, to ask the server "hey, is this cookie good, who is the user" ?

Or, you can flip the flow and have the webapp server, effectively _proxy_ the request to apigee and send in user data associated to the request. In other words the data flow is browser -> webapp server -> Apigee proxy. And there's a trusted link between the webapp server and the Apigee proxy, perhaps based on mTLS or some other mechanism. therefore Apigee can trust the request, trust that the webapp server has authenticated the user prior to relaying the request to Apigee.

That takes care of the first item.

Item #2 is "is the user authorized?" And to answer that you might want an externalized authz service, that Apigee can inquire: "I have user X, this user is asking for compensation information for user Y. Is this an authorized request?" (And remember it is possible that X == Y). And for that you need to build that ruleset or service, yourself. And maybe call out to it from Apigee via ServiceCallout.

Not applicable

I would suggest, using an encrypted value as identifier which can be unencrypted by Apigee to authenticate that is from a browser. Store the public key in Apigee KVM using which you will decrypt the value.

If Apigee cannot decrypt then throw an error.

Hi Priyadarshi,

But how can we ensure that request is sent from browser and not from other client like POSTMAN or SOAPUI

You need to ensure only the browser users will send that parameter and the private key will be stored in Apigee KVM, you can use that to verify.

How to ensure that only browser user will send that parameter. A developer using postman can also use that parameter