how might I set up trial access to APIs exposed through Apigee Edge?

Not applicable

Hi!

I would like to setup trial access to my APIs for customers/developers. I've got one solution but it's not elegant enough. I probably could setup custom attributes for developer's application (e.x. end of trial daytime), and check these values in pre flow of request.

However, such requests will still be managed by proxy endpoints. I would like to setup such trial access to reject requests before managing request in flow of the API.

Cheers, Tomas

Solved Solved
1 6 208
2 ACCEPTED SOLUTIONS

1506-credential-lifetime.png

Inside dev portal go to /admin/config/devconnect/apps

And change the value of Credential Lifetime to auto expire an API Key

View solution in original post

Hi @Tomasz Korecki . Yes, why not?

Fiddling with the API Key lifetime in the dev portal is one way to do it. This will work if you use the devportal to sign people up. It won't work if you allocate API keys in some other way - like through the Admin UI.

So here is another way to do it, using custom attributes on a developer application.

The way I figure it, you want the system to "default to closed". Therefore you want to deny access unless there is a custom attribute. You want to deny by default. The exceptions are: allow API access for some limited, pre-defined period of time. And, allow access if a member of the API Product Team have specifically altered the Developer App to grant access "forever" for that particular app. This modification would amount to ... adding a custom attribute to the developer app.

I would do this with a JS policy to do arithmetic, and a simple Condition + RaiseFault in the PreFlow.

OK, Let's suppose you're using APIKeys for API Security. The approach I will describe will also work for OAuth tokens, but it's simpler to illustrate for API Keys.

Within your API proxy, you have various flows. In each API Proxy you can insert a policy to perform Verification of the API Key. It is the VerifyApiKey policy and a configuration for same looks like this:

<VerifyAPIKey name="VerifyAPIKey-1">
    <APIKey ref="request.queryparam.apikey"/>
</VerifyAPIKey>

When this policy executes within a flow, it fills values into a number of different context variables. Among them are:

verifyapikey.VerifyAPIKey-1.issued_at 	
verifyapikey.VerifyAPIKey-1.apiproduct.developer.quota.limit 	
verifyapikey.VerifyAPIKey-1.status 	
verifyapikey.VerifyAPIKey-1.apiproduct.developer.quota.interval 	
verifyapikey.VerifyAPIKey-1.apiproduct.developer.quota.timeunit 	
verifyapikey.VerifyAPIKey-1.expires_in 	
verifyapikey.VerifyAPIKey-1.developer.app.name
verifyapikey.VerifyAPIKey-1.developer.id 
verifyapikey.VerifyAPIKey-1.developer.email 
verifyapikey.VerifyAPIKey-1.CustomAttributeHere
verifyapikey.VerifyAPIKey-1.apiproduct.name 

The "issued_at" variable reflects the time the API key was issued, in milliseconds since epoch. For example, July 8, 2015 would be represented as 1436383922540. This is the moment in time that the developer app was created and registered, whether through a developer portal or through the Admin UI, or through the Edge administrative API.

Knowing this, you can introduce some logic to "time-box" the access to your APIs. All you need is a condition that is the logical OR of the following:

  • less than 30 days (let's say) has elapsed since the apikey was created
  • the custom attribute called "permanently-approved" is available on the developer app

The Javascript logic needed to compute the elapsed time in days is:

var then = context.getVariable('verifyapikey.VerifyAPIKey-1.issued_at')
var now = (new Date()).valueOf();
var elapsed = now - then;  // in milliseconds

elapsed /= 1000; // convert to seconds
elapsed /= 60; // convert to minutes
elapsed /= 60; // convert to hours
elapsed /= 24; // convert to days
elapsed = elapsed.toFixed(0); // round to int

context.setVariable('days_active', elapsed);

and then in your PreFlow you need this kind of policy sequence:

<PreFlow name="PreFlow">
  <Request>
    <Step>
      <Name>VerifyAPIKey-1</Name>
    </Step>
    <Step>
      <Name>JS-ComputeElapsed</Name>
    </Step>
    <Step>
      <Name>RF-TimeExpired</Name>
      <Condition>(days_active > 30) OR (verifyapikey.VerifyAPIKey-1.permanently_enabled != "true")</Condition>
    </Step>
  </Request>
  <Response/>
</PreFlow>

The raisefault policy would look like this:

<RaiseFault name="RF-TimeExpired">
    <DisplayName>RF-TimeExpired</DisplayName>
    <Properties/>
    <FaultResponse>
        <Set>
            <Headers/>
            <Payload contentType="text/plain">Your Key has expired
</Payload>
            <StatusCode>400</StatusCode>
            <ReasonPhrase>Bad Request</ReasonPhrase>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

The way this would work for an OAuth token would be the same. Note: you'd need to look at the time the consumer ID was issued, not the time the oauth token was issued. In fact though, I'd put the time check into the proxy that issues oauth tokens, not in the proxy that validates oauth tokens.

View solution in original post

6 REPLIES 6

@Tomasz Korecki , Can you please explain little more about "I would like to setup such trial access to reject requests before managing request in flow of the API." ? Question in above form is difficult to answer.

Not applicable

@Anil Sagar Sorry for unclear question. I think something about setting up "disable" flag for customer key. Or changing status of dveloper's application from "Approved" to "Expired" automatically after some given period of time.

1506-credential-lifetime.png

Inside dev portal go to /admin/config/devconnect/apps

And change the value of Credential Lifetime to auto expire an API Key

Hi @Tomasz Korecki . Yes, why not?

Fiddling with the API Key lifetime in the dev portal is one way to do it. This will work if you use the devportal to sign people up. It won't work if you allocate API keys in some other way - like through the Admin UI.

So here is another way to do it, using custom attributes on a developer application.

The way I figure it, you want the system to "default to closed". Therefore you want to deny access unless there is a custom attribute. You want to deny by default. The exceptions are: allow API access for some limited, pre-defined period of time. And, allow access if a member of the API Product Team have specifically altered the Developer App to grant access "forever" for that particular app. This modification would amount to ... adding a custom attribute to the developer app.

I would do this with a JS policy to do arithmetic, and a simple Condition + RaiseFault in the PreFlow.

OK, Let's suppose you're using APIKeys for API Security. The approach I will describe will also work for OAuth tokens, but it's simpler to illustrate for API Keys.

Within your API proxy, you have various flows. In each API Proxy you can insert a policy to perform Verification of the API Key. It is the VerifyApiKey policy and a configuration for same looks like this:

<VerifyAPIKey name="VerifyAPIKey-1">
    <APIKey ref="request.queryparam.apikey"/>
</VerifyAPIKey>

When this policy executes within a flow, it fills values into a number of different context variables. Among them are:

verifyapikey.VerifyAPIKey-1.issued_at 	
verifyapikey.VerifyAPIKey-1.apiproduct.developer.quota.limit 	
verifyapikey.VerifyAPIKey-1.status 	
verifyapikey.VerifyAPIKey-1.apiproduct.developer.quota.interval 	
verifyapikey.VerifyAPIKey-1.apiproduct.developer.quota.timeunit 	
verifyapikey.VerifyAPIKey-1.expires_in 	
verifyapikey.VerifyAPIKey-1.developer.app.name
verifyapikey.VerifyAPIKey-1.developer.id 
verifyapikey.VerifyAPIKey-1.developer.email 
verifyapikey.VerifyAPIKey-1.CustomAttributeHere
verifyapikey.VerifyAPIKey-1.apiproduct.name 

The "issued_at" variable reflects the time the API key was issued, in milliseconds since epoch. For example, July 8, 2015 would be represented as 1436383922540. This is the moment in time that the developer app was created and registered, whether through a developer portal or through the Admin UI, or through the Edge administrative API.

Knowing this, you can introduce some logic to "time-box" the access to your APIs. All you need is a condition that is the logical OR of the following:

  • less than 30 days (let's say) has elapsed since the apikey was created
  • the custom attribute called "permanently-approved" is available on the developer app

The Javascript logic needed to compute the elapsed time in days is:

var then = context.getVariable('verifyapikey.VerifyAPIKey-1.issued_at')
var now = (new Date()).valueOf();
var elapsed = now - then;  // in milliseconds

elapsed /= 1000; // convert to seconds
elapsed /= 60; // convert to minutes
elapsed /= 60; // convert to hours
elapsed /= 24; // convert to days
elapsed = elapsed.toFixed(0); // round to int

context.setVariable('days_active', elapsed);

and then in your PreFlow you need this kind of policy sequence:

<PreFlow name="PreFlow">
  <Request>
    <Step>
      <Name>VerifyAPIKey-1</Name>
    </Step>
    <Step>
      <Name>JS-ComputeElapsed</Name>
    </Step>
    <Step>
      <Name>RF-TimeExpired</Name>
      <Condition>(days_active > 30) OR (verifyapikey.VerifyAPIKey-1.permanently_enabled != "true")</Condition>
    </Step>
  </Request>
  <Response/>
</PreFlow>

The raisefault policy would look like this:

<RaiseFault name="RF-TimeExpired">
    <DisplayName>RF-TimeExpired</DisplayName>
    <Properties/>
    <FaultResponse>
        <Set>
            <Headers/>
            <Payload contentType="text/plain">Your Key has expired
</Payload>
            <StatusCode>400</StatusCode>
            <ReasonPhrase>Bad Request</ReasonPhrase>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

The way this would work for an OAuth token would be the same. Note: you'd need to look at the time the consumer ID was issued, not the time the oauth token was issued. In fact though, I'd put the time check into the proxy that issues oauth tokens, not in the proxy that validates oauth tokens.

This is what I was thinking about, however you make it real. Thanks!

Glad to help!