ConsumerKey unicity (uniqueness) and organisations

Hi

We operate APIGee Edge Private in version 4.19.01. My question is regarding App ConsumerKey unicity/uniqueness. In APIGee documentation we noticied that the Consumerkey must be unique within an organisation.

For multitenancy purpose we want to have, for a specific developer, the same App ConsumerKey in 2 organisations. We tested to create the same ConsumerKey in the two organisation but we have a unicity error

{
"code": "keymanagement.service.ConsumerKeyAlreadyExists",
"message": "ConsumerKey already exists",
"contexts": []
}

Remark : We tried to do the same thing on Apigee SaaS platform and it's ok. Is there a specific behavior on Private Edge ?

Thanks for your support

Regards

Maxime

Solved Solved
1 3 226
1 ACCEPTED SOLUTION

Yes - I believe the way the key is stored in customer-managed Apigee Edge is such that it must be unique to the C* cluster.

There is a way to guarantee that it works.

I'm imagining that you have a sandbox and a production org. (Or the equivalent; the point is: two independent organizations). And you provision a client, including its credentials (key + secret) in one organization. And then at some later point, you want to "import" that credential into the other organization . Apigee Edge allows for import of a known credential with the Admin API; you can't do this (currently anyway) in the Admin UI. To import a credential, you specify the developer and app, and the key + secret. You probably already know about this; this Admin API call is throwing the error that you reported.

By the way, some people think that it is not such a good idea to have the same credential that works, and is accepted, across different organizations, like sandbox and production. That seems like a valid viewpoint to me; have you considered this? But I'll put this aside for now.

Your goal is that the client can use the same credential in different orgs. That doesn't necessarily mean the credential has to be stored in the same way for each organization. So ... what if ... instead of importing the original key (key1), you import a key that is derived from the original key (key1a). For example, import a key that consists of a fixed prefix, followed by the original key. If the original key is ABCDEFG12345, then import to the 2nd org, a key like "PROD-ABCDEFG12345".

This would allow you to use the bare credential in the sandbox org, something like this:

<VerifyAPIKey name='VAK-1'>
  <APIKey ref='request.header.apikey'/>
</VerifyAPIKey>

In other words, you verify the key exactly as it is passed in. And, in the production org, you do something different:

<AssignMessage name="AM-ApplyPrefixToKey'>
  <AssignVariable> 
    <Name>modifiedCredential</Name>
    <Template>PROD-{request.header.apikey}</Template>
  </AssignVariable>
</AssignMessage>

followed by

<VerifyAPIKey name='VAK-1'>
  <APIKey ref='modifiedCredential'/>
</VerifyAPIKey>

If you are using OAuthV2 (recommended), then you would need to do the analogous thing. For example, in a standard client_credentials grant, the client credentials are passed as a Basic Auth encoded Authorization header. Which means, in the prod org, you would need this series of policies:

  • BasicAuthentication / Decode - to decode the passed-in client id and secret
  • AssignMessage - to apply the fixed prefix (as shown above)
  • BasicAuthentication / Encode =- to encode a new BasicAuth header from the modified credential
  • OAuthV2/GenerateAccessToken - to generate a new token with those credentials.

You could also make the API Proxy logic smart, by wrapping the "credential augmentation logic" (the AssignMessage policy and etc) within a Condition that tests the organization.name context variable. The logic could run only when in the appropriate organization.

would this help?

View solution in original post

3 REPLIES 3

Yes - I believe the way the key is stored in customer-managed Apigee Edge is such that it must be unique to the C* cluster.

There is a way to guarantee that it works.

I'm imagining that you have a sandbox and a production org. (Or the equivalent; the point is: two independent organizations). And you provision a client, including its credentials (key + secret) in one organization. And then at some later point, you want to "import" that credential into the other organization . Apigee Edge allows for import of a known credential with the Admin API; you can't do this (currently anyway) in the Admin UI. To import a credential, you specify the developer and app, and the key + secret. You probably already know about this; this Admin API call is throwing the error that you reported.

By the way, some people think that it is not such a good idea to have the same credential that works, and is accepted, across different organizations, like sandbox and production. That seems like a valid viewpoint to me; have you considered this? But I'll put this aside for now.

Your goal is that the client can use the same credential in different orgs. That doesn't necessarily mean the credential has to be stored in the same way for each organization. So ... what if ... instead of importing the original key (key1), you import a key that is derived from the original key (key1a). For example, import a key that consists of a fixed prefix, followed by the original key. If the original key is ABCDEFG12345, then import to the 2nd org, a key like "PROD-ABCDEFG12345".

This would allow you to use the bare credential in the sandbox org, something like this:

<VerifyAPIKey name='VAK-1'>
  <APIKey ref='request.header.apikey'/>
</VerifyAPIKey>

In other words, you verify the key exactly as it is passed in. And, in the production org, you do something different:

<AssignMessage name="AM-ApplyPrefixToKey'>
  <AssignVariable> 
    <Name>modifiedCredential</Name>
    <Template>PROD-{request.header.apikey}</Template>
  </AssignVariable>
</AssignMessage>

followed by

<VerifyAPIKey name='VAK-1'>
  <APIKey ref='modifiedCredential'/>
</VerifyAPIKey>

If you are using OAuthV2 (recommended), then you would need to do the analogous thing. For example, in a standard client_credentials grant, the client credentials are passed as a Basic Auth encoded Authorization header. Which means, in the prod org, you would need this series of policies:

  • BasicAuthentication / Decode - to decode the passed-in client id and secret
  • AssignMessage - to apply the fixed prefix (as shown above)
  • BasicAuthentication / Encode =- to encode a new BasicAuth header from the modified credential
  • OAuthV2/GenerateAccessToken - to generate a new token with those credentials.

You could also make the API Proxy logic smart, by wrapping the "credential augmentation logic" (the AssignMessage policy and etc) within a Condition that tests the organization.name context variable. The logic could run only when in the appropriate organization.

would this help?

Hi

Thanks very much for this detail answer. You confirm that keys unicity is managed to C* level and not org level

To clarify we would like to have same key in several orgs as we want to distribute our APIs in differents orgs : Premium, Basic, ... I know this topic is shared by some companies using APIGee onprem regarding API increase. The objective is to separate API in order to manage admin access

So your suggestion is a good way, we will study it

Best Regards

Maxime

Hi


A question regarding key unicity ... The uncity seems to be on the org in APIGeee SaaS platform

Do you plan to restrict key unicity to the org on Private Edge ?


BR

Maxime