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?