How can I revoke a key without storing it?


#1

We’re currently building a WordPress plugin to integrate a developer portal with WP. The workflow is as follows:

  1. User registers as developer -> automatic registration on Tyk API as a developer
  2. Get list of policies (each representing access to an API)
  3. User chooses a policy -> key request is submitted on Tyk API (and optionally, automatically approved)
  4. Token is saved as key_request_id / token_name (user input) / policy_id

For security reasons, we’d rather not store the token itself, we just show that to the user once.
I’m trying to find out how a user could revoke one of his tokens. The tokens API expects you to know the api_id and token. The api_id is tricky since a policy can allow access to several APIs, so we don’t know the api_id for sure. The token itself we don’t have at all.

Do you see a solution here? For example, if tokens had an unique ID we could store that and use it to revoke the token.
Or do we have to store the token for this to work?

Thanks
Christof


#2

So the way we get around this issue is by storing a hash of the token everywhere in Tyk by default, and there’s an endpoint for the portal to revoke hashed keys but in order for this to work you need to have key hashing enabled.

If yu are mirroring developers in the portal and generating tokens using key requests, then the key request returns the raw key, you can get the hashed key from the developer record, where it is stored alongside the policy ID.

You could, if the above is true in your setup, then use the dashboard developer revoke API (not documented) to revoke the token.

(In the dash, if you view a developer record you’ll see their keys and the ability to revoke them using a revoke button), this would be the API we wouldnusenkn this case to revoke a token without storing it.


#3

Thanks for the quick response Martin.

I see. Our tyk instance is running in hashed key mode anyway (Tyk is running in hashed key mode), but I haven’t yet found where that is configured.

When I fetch developer details I see:
"api_keys": { "": "8811bf2e" },
I assume the empty bit is the api_id and the value is the hashed key. Not sure why the api_id would be empty, maybe because the developer was signed up for a plan?

Developers should always be registering for a plan/policy, correct (Create a key request)? Where is the api_id coming from for the key?

With the hashed ID, I should be able to do:
DELETE /api/portal/developers/key/8811bf2e
?

Thanks again.


#4

That segment is for v1 key requests (bound to API ID and not policy ID), your developer object should have a subscriptions element (your key request will have a version flag for “v2” if you look at the ones the portal generates, this is really important):

{
	"id": "5696411a30c55e1fd6000002",
	...
	"subscriptions": {
		"5654566b30c55e3904000003": "33c7f8be",
		"56b9d3fe30c55e2afa000003": "e9416166"
	},
	...
}

Reasoning The portal grants access to policies not APIs, because a policy can encapsulate ACL for multiple managed APIs (there is a difference between what is published and what is managed, you may not want to expose all your microservices, but instead bundle a group of microservices as a single “API” for the developer portal, we moved to the v2 version of key requests and catalogue entries a long time ago)

The item on the left is the policy ID that the token is bound to and the right element is the hashed token ID.

Revoke the key for a developer object:

We also want the API Call to update the developer record in the portal so you can manage their keys / usage and subscriptions from there so this call is preferable to just deleting the token as the references will not be removed in the call you suggest.

DELETE http://skaffen.tyk.io:3000/api/portal/developers/key/{policy-id}/{hash}/{developer-id}

#5

Ah, now I see where I went wrong, I wasn’t on v2. I just tested with a v2 key request and now when I query the developer I get the subscriptions array. And, I can revoke the key just as you say.

My only problem now is that I get the RawKey when I approve a key request and I have no real way to match that key with the hashed ones I get when I query the developer. Do you see a way to do this?


#6

Ah, yes, you’ll need to match on the policy ID (“for plan”), the raw key is for the developer only


#7

Will do, thx again Martin.


#8

Have there been changes to the API recently? It seems like certain things that were working before no longer are.

Create a developer:

POST https://admin.cloud.tyk.io/api/portal/requests
{
   "by_user": "57a1b17da147100001000016",
   "for_plan": "57a1af71f5a67a0001000022",
   "date_created": "2016-08-03T14:49:20.992-01:00",
   "version": "v2"
}

>> RESPONSE

{
  "Status": "OK",
  "Message": "57a1e45a897fce0001000008",
  "Meta": null
}

Approve key request:

PUT https://admin.cloud.tyk.io/api/portal/requests/approve/57a1e45a897fce0001000008

>> RESPONSE

{
  "RawKey": "",
  "Password": ""
}

Normally I’d get a key here… I also tried sending the key request with approved: false, then approving it in the Tyk Dashboard. Anyway, when I get the developer:

GET https://admin.cloud.tyk.io/api/portal/developers/57a1b17da147100001000016

>> RESPONSE

{
  "id": "57a1b17da147100001000016",
  [...]
  "inactive": false,
  "api_keys": {},
  "subscriptions": {},
}

The subscriptions object is empty. What am I missing? :confused:

Thanks


#9

Hi,

What kind of policy are you exposing?

The policy needs to be active, all ACL elements need to be of the same with type, and none can be “Open”.

That might be what’s causing the issue.

M.


#10

Hi Martin

It’s a new Dashboard with minimal configuration that I created on cloud.tyk.io for this test case. The policy:

  • has access rights to the API
  • is active
  • has no other configuration besides a tag

#11

I just tried this workflow with a test account on our cloud, so I am certain the flow and API calls are correct. So I think the issue is in the policy.

The API that is being granted access to, is it “closed” as in, it’s using an Auth Token as it’s security method?


#12

The API is using Auth Token with Authorization header.
I’ll send you an email with the test account I’m using, hope that’s ok.