How can I store app-specific data in Apigee Edge? Trying with KVM, it's not working.

Not applicable

Original title: Can I enable CPS in the on premises version of Apigee Edge? If so, How?

Every app that gets created will add 2 data items. On key regeneration, I want these values to be transferred over to the new client id as well.

I'm looking to use the Edge KVM for this purpose. When I try to POST to KVM to update the map, it does not work as I want. The KVM has a few hundred key-value entries. The management UI displays this msg: "This map is too large to manage in the UI".

When I try to make the API call, I get the following msg:

{
  "code": "keyvaluemap.service.KeyValueMapOperationNotSupported",
  "message": "KeyValueMap Operation CreateKeyValueMapEntry is not supported for the organization ABCD",
  "contexts": []
}

We are using Apigee software on our own systems. Version 4.16.05.02

Should I look at some other mechanism, besides KVM, to save this information?

Solved Solved
2 10 1,009
1 ACCEPTED SOLUTION

Every app that gets created will add 2 entries in the KVM. On key regeneration, I want these values to be transferred over to the new client id as well.

Ahhh, yes... You should use custom attributes on the app.

In Edge, the hierarchical model for entities is:

  • developer
    • app
      • credential (== client_id + secret)

And you can attach attributes to any level of that hierarchy. From within the Edge UI, you can read and update the custom attributes on the developer, or on the app. From within the Edge UI, you cannot see or manage the attributes on a credential. For any of the 3 entity types, you can read and update custom attributes via the Apigee Edge administrative API. But I think you don't want to store credential-specific (aka client_id specific) data. You want the data to be attached to an App. And that's easy to do from within the Edge Administrative UI. Here's what it looks like:

4165-developer-app-details.png

(Oops! you said OPDK, so I guess you will be seeing a different style of page for Developer App Details. But you will see the same information if you are on the current patch level.)

And, every time an API request arrives bearing the API key, or a token derived from that API key, and your API proxy invokes VerifyApiKey or VerifyAccessToken, respectively, the message context will have access to these custom attributes, implicitly . So you could do whatever you like with that data.

Regarding regeneration, here is a side note: In current versions of Edge you do not "regenerate" the client_id, you can simply add a new client_id, and maybe if you like remove the old one. And those client_id's will be unique and will have independent and possibly overlapping lifetimes. But there is no "regenerate". In fact the old "regenerate" did nothing but delete the old client_id and add a new one. Today (latest OPDK), those operations are explicitly separated in the UI.

Regardless of the number of credentials configured for the app, the custom attributes will be available in the message context directly after the API proxy validates any valid non-expired, non-revoked token or client_id.

You are limited to, I think, 20 attributes. I apologize for the uncertainty, check the doc to be sure. The reason I don't know: I never use 20, or more than about 4 or 5. If I have a whole bunch of stuff to store, I put it into a JSON string, and store that string as the value of the custom attribute. Then it can be flexible and I can write a simple JavaScript callout to parse the JSON out of the custom attribute and do what I want with it.

As another example, I have stored PEM-encoded public keys into custom-attributes attached to apps. Then at runtime, the API proxy can de-serialize the public key and verify a signed payload, knowing that it was signed by the holder of the private key (the app).

And yes, you can read and update those attributes via administrative API calls. Or, you can attach attributes at the time you create the app. This looks like the following:

POST :mgmtserver/v1/o/:orgname/developers/developer@example.com/apps
Content-type: application/json
Authorization: :edge-auth

{
  "attributes" : [ {
    "name" : "key-1",
    "value" : "attrvalue-put-anything-you-like-here"
  }, {
    "name" : "key-2",
    "value" : "another-value-here"
  }, {
    "name" : "key-3",
    "value" : "{ \"prop1\" : \"value1\" }"
  }
  ],
  "apiProducts": [ "ValidProductNameHere" ],
  "keyExpiresIn" : "86400000",
  "name" : "AmitTestApp"
}

The value for each attribute MUST be a string; you cannot put a JSON hash there directly. If you want a JSON value, stringify the object, and then store the resulting string. (it means all the quotes will be escaped). BTW, unrelated to custom attributes, the keyExpiresIn value is in milliseconds. Omit it, if you want a never-expiring key.

To directly answer your question, though: KVM is not appropriate for storing app-specific data. Instead, use custom attributes attached to the app.

View solution in original post

10 REPLIES 10

Every app that gets created will add 2 entries in the KVM. On key regeneration, I want these values to be transferred over to the new client id as well.

Ahhh, yes... You should use custom attributes on the app.

In Edge, the hierarchical model for entities is:

  • developer
    • app
      • credential (== client_id + secret)

And you can attach attributes to any level of that hierarchy. From within the Edge UI, you can read and update the custom attributes on the developer, or on the app. From within the Edge UI, you cannot see or manage the attributes on a credential. For any of the 3 entity types, you can read and update custom attributes via the Apigee Edge administrative API. But I think you don't want to store credential-specific (aka client_id specific) data. You want the data to be attached to an App. And that's easy to do from within the Edge Administrative UI. Here's what it looks like:

4165-developer-app-details.png

(Oops! you said OPDK, so I guess you will be seeing a different style of page for Developer App Details. But you will see the same information if you are on the current patch level.)

And, every time an API request arrives bearing the API key, or a token derived from that API key, and your API proxy invokes VerifyApiKey or VerifyAccessToken, respectively, the message context will have access to these custom attributes, implicitly . So you could do whatever you like with that data.

Regarding regeneration, here is a side note: In current versions of Edge you do not "regenerate" the client_id, you can simply add a new client_id, and maybe if you like remove the old one. And those client_id's will be unique and will have independent and possibly overlapping lifetimes. But there is no "regenerate". In fact the old "regenerate" did nothing but delete the old client_id and add a new one. Today (latest OPDK), those operations are explicitly separated in the UI.

Regardless of the number of credentials configured for the app, the custom attributes will be available in the message context directly after the API proxy validates any valid non-expired, non-revoked token or client_id.

You are limited to, I think, 20 attributes. I apologize for the uncertainty, check the doc to be sure. The reason I don't know: I never use 20, or more than about 4 or 5. If I have a whole bunch of stuff to store, I put it into a JSON string, and store that string as the value of the custom attribute. Then it can be flexible and I can write a simple JavaScript callout to parse the JSON out of the custom attribute and do what I want with it.

As another example, I have stored PEM-encoded public keys into custom-attributes attached to apps. Then at runtime, the API proxy can de-serialize the public key and verify a signed payload, knowing that it was signed by the holder of the private key (the app).

And yes, you can read and update those attributes via administrative API calls. Or, you can attach attributes at the time you create the app. This looks like the following:

POST :mgmtserver/v1/o/:orgname/developers/developer@example.com/apps
Content-type: application/json
Authorization: :edge-auth

{
  "attributes" : [ {
    "name" : "key-1",
    "value" : "attrvalue-put-anything-you-like-here"
  }, {
    "name" : "key-2",
    "value" : "another-value-here"
  }, {
    "name" : "key-3",
    "value" : "{ \"prop1\" : \"value1\" }"
  }
  ],
  "apiProducts": [ "ValidProductNameHere" ],
  "keyExpiresIn" : "86400000",
  "name" : "AmitTestApp"
}

The value for each attribute MUST be a string; you cannot put a JSON hash there directly. If you want a JSON value, stringify the object, and then store the resulting string. (it means all the quotes will be escaped). BTW, unrelated to custom attributes, the keyExpiresIn value is in milliseconds. Omit it, if you want a never-expiring key.

To directly answer your question, though: KVM is not appropriate for storing app-specific data. Instead, use custom attributes attached to the app.

Thank you for the detailed response.

Looks like the custom attributes are available via management APIs. Can these be extracted via flow variables?

We integrate with our own custom token provider. In our existing setup, the client_id/secret does get regenerated via the dev-portal. We have some custom logic (for some other integration point) for which we need a a couple of attributes available at the app level.

I'll explore the custom attributes mechanism, since KVMs will not scale for our use case.

regarding re-generation - no problem. If you attach the newly generated client {id+secret} to the same developer app, then the custom attributes that you have applied to the developer app will still be available with the new credential.

I'll explore the custom attributes mechanism, since KVMs will not scale^H^H^H^H^H^H are inappropriate for our use case.

FTFY. Please don't misunderstand. the summary of my answer is not "use something other than KVM because KVMs won't scale." The KVM scales just fine, but the KVM,as i said above, is not appropriate for what you want. Instead, custom attributes were designed specifically for what you're asking about. I'm only encouraging you to use the right tool for the job!

For the record, I do not appreciate my posts getting edited automatically to fit the answer being posted.

Yep - sorry about the surprise there. The whole idea here is that questions and answers ought to benefit the community. Your question presupposed "The answer" as KVM, and also CPS!! when in fact the answer was neither KVM nor CPS, and either of those keywords would only confuse people or mislead them unnecessarily. The real problem you faced was "how to store app-specific metadata?" The answer to that is definitely "custom attributes on the app". The edit I made to the subject of your question here (as curator of the community) was aimed only at helping others too. Removing the misleading assumption, and allowing better search. After modifying the subject, I've answered your actual question (value to you), and I'm also helping other people, so.... win/win? I know the subject change was a surprise, but I hope it's a good one.

No worries.

Custom attributes is the right choice. Will explore this further.

Thanks.

Is there a policy that I can use to update custom attributes during a proxy call flow?

no, there is no policy that allows you to modify app attributes during API proxy flow.

I think Apigee probably has somethinig to satisfy your need though.

Can you please ask a new question, and we can figure it out there?

To answer the original question: No, you cannot enable CPS in on-premises versions of Apigee Edge.

Not sure how I missed this answer. Thanks for the information.