How to retrieve KVM entry form developer custom attribute set as reference to the KVM Key?

Hi,
I am trying to design a solution with KVM entries which is going to enable 3rd party integration through the backends that we already integrated. These backends are providing apikeys for each client and different for all environments.
So with KVM I want to store on the scope of environment for client apikeys under one generalised encrypted KVM store.

"KVM-DataStore" will have;
	KEY	    VALUE
x-client-apikey: 'xxxxxxxxxx',
y-client-apikey: 'yyyyyyyyyy',
z-client-apikey: 'zzzzzzzzzz'
For accessing these key-value pairs on the proxy level is not possible to do it generic. So for solving that I have custom attributes created on developer account that attribute will keep the reference of KVM-DataStore's key and all developer accounts will have same attrs key as 'integrationApiKey' for example;

"x-developer@example.com" developer account will have custom attribute as below;

 "integrationApiKey" : "x-client-apikey" 

"y-developer@example.com" developer account will have custom attribute as below;

 "integrationApiKey" : "y-client-apikey"


So to have these mapping in proxy I have already AccessEntity that retreives developer attrs,
As well as Extract Variables that extract these custom attrs from developer accounts;

Only part is could't be solved for KVM that how do I provide these references under Get KVM values?

Here is my AE-policy;

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessEntity async="false" continueOnError="false" enabled="true" name="AE-DeveloperAttributes">
    <DisplayName>AE-DeveloperAttributes</DisplayName>
    <Properties/>
    <EntityIdentifier ref="client_id" type="consumerkey"/>
    <EntityType value="developer"/>
</AccessEntity>

and EV policy;

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-GetAPIKeyReference">
    <DisplayName>EV-GetAPIKeyReference</DisplayName>
    <Properties/>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <XMLPayload>
        <Variable name="apikey_ref" type="string">
            <XPath>/Developer/Attributes/Attribute[Name='integrationApiKey']/Value/text()</XPath>
        </Variable>
    </XMLPayload>
    <Source>AccessEntity.AE-DeveloperAttributes</Source>
</ExtractVariables>

and KVM policy;

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="KVM-GetAPIKey">
    <DisplayName>KVM-GetAPIKey</DisplayName>
    <Properties/>
    <MapName>KVM-DataStore</MapName>
    <MapName ref="apikey_ref"/>
    <Get assignTo="private.APIkey">
        <Key>
            <Parameter ref="apikey_ref"/>
        </Key>
    </Get>
    <Scope>environment</Scope>
</KeyValueMapOperations>

So to solve this I wanted to have generic parameter being passed into "apikey_ref" flow variable after Extract variable policy ran. And in theory with that configuration only part would remain on to set for additional clients to have these attrs on their developer account as a reference of key in the KVM. Any idea what would be problem in here that is not possible to get the apikey from KVM store? Whenever I passed this apikey_ref into KVM I would expect this would retreive to me a kvm entry is being configured.
And In the trace tool I can see that apikey_ref is having value as a x-client-apikey / y-client-apikey / ... etc.

Pinging you guys might solve this already as a scenario somewhere?

@Dino @Sai Saran Vaidyanathan @Geir Sjurseth @Ozan Seymen


Thanks,
Hasan

0 8 362
8 REPLIES 8

@HS Bilgen

I am assuming you are using Apigee X or hybrid

In your KVM policy, you have MapName twice. If you are using just one KVM, you dont need to use the variable.

You could use

<KeyValueMapOperations mapIdentifier="KVM-DataStore" async="false" continueOnError="false" enabled="true" name="KVM-GetClientID">
  <DisplayName>KVM-GetClientID</DisplayName>
  <ExpiryTimeInSecs>86400</ExpiryTimeInSecs>
  <Scope>environment</Scope>
  <Get assignTo="private.APIkey">
      <Key>
          <Parameter ref="apikey_ref"/>
      </Key>
    </Get>
</KeyValueMapOperations>

One more note

If you are passing the Apigee client Id or token to the proxy call and using Verify API Key or VerifyAccessToken, the custom attribute should be populated automatically as a variable (check trace). You can use that variable directly instead of using the AccessEntity and Extract Variable policy

Using Apigee Cloud, I had used this way either but this doesn't work with ref='apikey_ref' .

And for MapName; mapName twice is I got it from apigee documents here; https://cloud.google.com/apigee/docs/api-platform/reference/policies/key-value-map-operations-policy I thought that helps to use flow variables to provide kvm key references. Anyway that didn't work too.

Example that you showed is not working to pass key reference from flow variables. I could't get the apikey to put it in req.header through backend.

I'm sorry you're having troubles.

I'll ask that we make the documentation clearer on this point.

In the meantime, it's still not working for you. I suggest that you break down the problem. Rather than linking up apigee client_id or developer attribute, and so on.... first make sure you can PUT and GET from a KVM easily.

Attached is an example proxy that shows the use of the MapName element.

apiproxy-kvm-maintenance-20210415-073447.zip

Check it out, maybe it will help you get past this challenge. After you sort out the KVM part, then link in the developer attribute part.

Hi @dchiesa1 ,
I'm with the same problem. I downloaded you zipped apiproxy and uploaded in my environment.
And it still doesn't working. When I try set a new variable, the MapName policy doesn't set the current value from query param or even the default value ("settings").

It always is creating a new variable into a default map identifier called "kvmap".
michel_silva_05_0-1679431231128.png

Is there something related with apigee edge version?

I also tried set the MapName as literal String, but still doesn't working:

michel_silva_05_1-1679431443043.png

 

You're using the mapname attribute in your KVM policy. This works with the Apigee X / Hybrid version of the policy, not for Edge which seems to be what you're using

https://docs.apigee.com/api-platform/reference/policies/key-value-map-operations-policy

I'm sorry, this is confusing. 

I don't believe the MapName element is supported in the KeyValueMapOperations policy in Apigee Edge.  The documentation for that is here. That element is supported in the Apigee X and hybrid versions of the Policy. 

As such, your KeyValueMapOperations policy specifies no KVM identifier, therefore, it is using the default of kvmap. 

Hi @dino I think we are fine with retreiving any KVM on any other proxies.
Just wanted to make this scenario to being pass through with dev attrs I have been using all the policies almost with no issues. this one is only part I wanted to pass flow var as a reference to the KVM from dev attr. Would there be a possible way of doing that?

Hi hsnbilgen, you can also retrieve custom attributes by using a verify api key policy

https://cloud.google.com/apigee/docs/api-platform/reference/policies/verify-api-key-policy#flowvaria.... If you need to use an API Key issued by your backend sytems (and not by apigee) you can also inject custom client_id and client_secret in your user's app credentials https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/v1/organizations.developers.apps.key...