Issue using encrypted KVM

Hi,

I've an issue using encrypted KVM, the Proxy works fine if I'm trying to get values from Un-encrypted KVM but the issue begins if I use an encrypted KVM

I see the query param in outbound request when I use un-encrypted KVM and the request is successful.

    <Get assignTo="request.queryparam.key">
        <Key>
            <Parameter>required_key</Parameter>
        </Key>
    </Get>

But when I try to use encrypted KVM I dont see the query param in outbound request and the request is failed.

    <Get assignTo="private.request.queryparam.key">
        <Key>
            <Parameter>required_key</Parameter>
        </Key>
    </Get>

Is there anything that I'm missing. I don't see any errors from processing the step but the backend returns error due to missing key.

1 3 537
3 REPLIES 3

Well let's see.

As you may be aware, there's a restriction when performing a GET using an encrypted KVM: the assignTo variable must have the prefix "private." I forget what happens if you don't use the private. prefix, I think you get a validation error at the time you try to save the API proxy. Whether you get the error then, or later, in any case , it won't work.

Variables named with the "private." prefix are treated specially in the Apigee Edge runtime. The values assigned to such variables will not be shown in the Edge Trace (Debugsession). This preserves privacy of the data.

I see you have used a name that begins with "private." and then finishes with "request.queryparam.key". And from that name, and from your example using the un-encrypted KVM, I am inferring that you'd like to set a queryparam named "key" with the data you retrieve from the encrypted KVM.

Two things on that.

  1. in general, setting a variable private.X is not the same as "quietly" setting the variable X. In particular, setting the variable "private.request.queryparam.key" does not quietly set the actual context variable request.queryparam.key. It's not the case that the "private." prefix sets a variable with a different name, only quietly. Setting the variable with the name "private.request.queryparam.key" does not have any effect on the queryparams in the request object.
  2. It does not make sense to use an encrypted KVM to store data presumably because it is secret, and then put that data into a query param! And transmit it over the network. The query param is not secret at all, and will be logged in web logs on the target system, and also in logs on the Apigee side. So this seems like a bad idea. If you really are putting data into the queryparam, it's not a secret, so don't use encrypted KVM. If you really have a secret, don't put it into a query param.
  3. (Bonus thing) If you really want to read frrom an encrypted KVM and then set a queryparam with that data, then... Use two policies. One KeyValueMapOperations/GET and use "private.data" or whatever. Then use AssignMessage/AssignVariable and explicitly assign the value in "private.data" to "request.queryparam.key". But if you do this, it really seems to me that you are not using the Apigee Edge system correctly.

@Raju

The first policy without encrypted value works, since Apigee sees the reference as request.queryparam.key, which is a defined flow variable. In the second policy with private.request.param.key, Apigee will create a variable with name "private.request.query.param.key", the "private" is like a variable prefix. Variables request.param.key and private.request.param.key are hence not treated as the same variable references. That's the reason its not passed to your backend. You can test it by writing a JS policy to print the values

print(context.getVariable("request.queryparam.key"));

print("key value with private prefix");

print(context.getVariable("private.request.queryparam.key"));

You will see that the output of the first print statement will be empty, while the third statement will give you the required value.

You will need to explicitly set the value in request.queryparam.key using Assign Message or JavaScript policy, after retrieving the value from the KVM. Here is an example

<Get assignTo="private.request.queryparam.key">
  <Key><Parameter>required_key</Parameter></Key>
</Get>
<AssignMessage name="AM-Set-Key">
  <Set>  
    <QueryParams>
      <QueryParam name="key">{private.request.queryparam.key}</QueryParam>
    </QueryParams>
  </Set>
  <AssignTo type="request" transport="http" createNew="false"/>
</AssignMessage>

this works; it is basically what I described in #3 in my answer.