We are an Apigee Edge enterprise customer. Most of the proxies that we published on the Apigee Edge use oAuth2.0 authentication between the consumer & Apigee proxy.
Consumer (system)[1] <-> Apigee[2] <-> Target endpoint[3].
There is a new use case, where the consumer[1] doesn’t want to use the Apigee[2] as an authorization server. Instead, they want to use Microsoft Entra.
The team will provide the Application identity (principal) to the Apigee proxy[2], we need to validate the identity(access token) of the consumer[1]. If it is valid, Apigee should make a call to the Target endpoint[3].
Can anyone please provide some guidance - how to implement the above? @dchiesa1 Thanks in advance.
the consumer[1] doesn’t want to use the Apigee[2] as an authorization server. Instead, they want to use Microsoft Entra.
The team will provide the Application identity (principal) to the Apigee proxy[2], we need to validate the identity(access token) of the consumer[1]. If it is valid, Apigee should make a call to the Target endpoint[3].
This is pretty straightforward. There are some nuances.
As far as I understand Entra ID will act as an OIDC provider. The consumer connects to EntraID , goes through the OIDC token grant process, and the result is an ID token and an access token. In most cases with OIDC that I have seen, both tokens are JWT, signed with a private RSA key.
Apigee includes a VerifyJWT policy. If you configure the VerifyJWT policy to point to the JWKS endpoint of the EntraID tenant, then, Apigee can retrieve the public keys for EntraID, and verify the access token. If VerifyJWT succeeds, then the token is good, authentic, not expired, and issued by EntraID. Which means your Apigee proxy can "trust" the claims in the token. you can configure the proxy, At that point , to call the upstream/backend/target system.
Now for the nuance. One of the cool things about Apigee is the API Product concept. If you just configure Apigee to verify a JWT that was issued by some other issuer, that will "work", but it doesn't have any reliance on the API product. Which means you get none of the API product coolness, like automatic authorization checks for the operation (the {verb,path} pair), or metadata like Quota / rate limits or other custom attributes. You don't get the API analytics.
To solve this , you can synchronize the clientid that you use in EntraID, with the clientID in Apigee. Create the client app in EntraID, and then "import" that clientID as a "consumer key" into Apigee, with authorization for one or more API products. Then, you can configure the proxy to:
Hi @dchiesa1
I'm also referring to this thread for the same use case. Would you mind clarifying the last part about solving the nuance? And are there any documentations on how to import the clientID from Entra ID into Apigee?
Thanks.
For importing a credential, you can use the documented REST API
POST :apigee/v1/organizations/:org/developers/:dev/apps/:app/keys/create
Authorization: Bearer :token
content-type: application/json
{
"apiProducts": ["Product1", "Product2"],
"consumerKey": "REQUIRED",
"consumerSecret": "REQUIRED",
"expiresInSeconds": "864000"
}
The Developer, and the App , must already exist.
In the payload above, the consumerKey is the "client ID" that you get from Entra ID. I don;t know how you'd get that, but I guess there is an API you can use to find that thing.
The consumerSecret may also be something that EntraID offers, but ... you probably don't need that, since the security of the credential depends on the signature provided by EntraID on the JWT ID token. So the consumerSecret in Apigee is essentially unused. You could place any string in there, I would probably use something like "not-needed" or similar. (not sure if there is a minimum character length for that secret.)
The expiresInSeconds can be -1 for "never" or some quantity, if you like to enforce rotation of credentials. Probably if entraID is the system of record, then you don't want Apigee to manage an expiry of the credential.
If the app exists, then ... it probably already has a credential associated to it. Apigee has an interesting model - it allows a single "app registration" to have multiple credentials (consumer key/secret pairs), and each has an independent lifetime. This supports credential rotation, while keeping the app the same entity. So any custom attributes are tied to the app, which remains the same, as opposed to the credential, which may change. Anyway, if you are using EntraID to provide the consumerKey, what you ought to do is remove any of the OTHER credentials attached to the app.
I think you can do this:
DELETE :apigee/v1/organizations/:org/developers/:dev/apps/:app/keys/:clientid_to_remove
Authorization: Bearer :token
What some people have done is, tap into the app provisioning motion, whatever that is. Often it's done as part of an interaction with a developer portal. When that happens, you can trigger a process that
There is no webhook, sadly, for the event of "an app has been created" in Apigee. but, you have options:
You might need both (belt & suspenders) to insure reliable behavior.
Conversely if you are not using the Apigee dev portal to provision apps, and instead you are using some UI that is connected to EntraID to provision apps, then, the process is somewhat different
If you are invested in GCP, you might want to look at Application Integration , to manage the process that interrogates or updates the various systems involved.
Hi @dchiesa1
Thank you @dchiesa1 . I got it, could you please provide any documentation to implement this pattern.