Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Currently content update is done by the user who created it which creates problem and is complex in scenarios where an admin want to update content by retired user. There should be an easy way to allow users to update content at the same time it should have authentication.

Solution Approach 

approach 1 :

There should be a way to allow certain operations and for that we need to maintain master keys. These master keys would be created and stored through API by admin and would be used by anyone to bypass the current authentication mechanism which restricts some flow.

...

No Format
nopaneltrue
POST /v1/masterkey/verify

Request body : 

{
	request : {
		"channel" : "sunbird",
		"key" : "1fb786d3-45c2-447d-b657-f9768da15348"
	}
}

Response body : (Success) 200

{
  "id": "api.masterkey.verify",
  "ver": "v1",
  "ts": "2019-01-29 09:17:31:909+0000",
  "params": {
    "resmsgid": null,
    "msgid": "9db786d3-45c2-447d-b657-f9768da15652",
    "err": null,
    "status": "success",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
	}
}

Response body : (Error) 400

{
    "id": "api.masterkey.create",
    "ver": "v1",
    "ts": "2018-01-29 11:12:31:853+0000",
    "params": {
        "resmsgid": null,
        "msgid": "8e27cbf5-e299-43b0-bca7-8347f7e5abcf",
        "err": "INVALID_KEY",
        "status": "KEY_NOT_EXISTS",
        "errmsg": "Provided key for channel sunbird is invalid"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        }
}


approach 2:

Previous approach is configured to create a master key only based on channel. This can be modified to create a master key based on organisation too. The changes we will have is we can pass type in the request too. The generated key will be stored with type and value as (channel, abc) or (orgId, "org01") 

No Format
nopaneltrue
Request body : 

{
	request : {
		"value" : "sunbird", 
		"type" : "channel"  //channel or orgId
	}
}

get API will be modified to include the type

GET /v1/masterkey/{type}/{value}

The verify API will include additional type parameter

No Format
nopaneltrue
{
	request : {
		"value" : "sunbird",
		"type" : "channel",
		"key" : "1fb786d3-45c2-447d-b657-f9768da15348"
	}
}

This also means that table will have another column "type" and it will be used to fetch key accordingly.

Other behavior remains same

approach 3:

In previous two approaches we are considering a master key which will be expired after certain duration. But it can be modified to include a refresh token which can be used to generate a new master key.  Note that refresh token has it's own expiry, post that it requires to create a new master key and refresh token by create API call.

The benefit of this is that it helps in mitigate leaking of master key by making the expiry duration of short intervals. 

No Format
nopaneltrue
POST /v1/masterkey/create

Request body : 

{
	request : {
		"channel" : "sunbird"
	}
}

Response body : (Success) 200

{
  "id": "api.masterkey.create",
  "ver": "v1",
  "ts": "2019-01-29 09:17:31:909+0000",
  "params": {
    "resmsgid": null,
    "msgid": "9db786d3-45c2-447d-b657-f9768da15652",
    "err": null,
    "status": "success",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
		"key" : "1fb786d3-45c2-447d-b657-f9768da15348",
		"expiresOn":  120,
		"refreshToken": "3ab586d3-45c2-447d-b657-g9768da13730"
	}
}

request to regenerate the key need refresh token

{
	request : {
		"channel" : "sunbird",
		"refreshToken": "3ab586d3-45c2-447d-b657-g9768da13730"
	}
}

Response body (Success : 200)

{
  "id": "api.masterkey.create",
  "ver": "v1",
  "ts": "2019-01-29 11:17:31:909+0000",
  "params": {
    "resmsgid": null,
    "msgid": "9db786d3-45c2-447d-b657-f9769da15652",
    "err": null,
    "status": "success",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
		"key" : "3gh686e3-45c2-447d-b657-b3364da84351",
		"expiresOn":  120,
		"refreshToken": "3ab586d3-45c2-447d-b657-g9768da13730"
	}
}


There would be a TTL on the refresh token, so as the entry gets removed after refresh token expiry and then it would require to create a fresh entry.


get API response

No Format
nopaneltrue
{
  "id": "api.masterkey.create",
  "ver": "v1",
  "ts": "2019-01-29 11:18:31:909+0000",
  "params": {
    "resmsgid": null,
    "msgid": "9db786d3-45c2-447d-b657-f9769da15652",
    "err": null,
    "status": "success",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
		"key" : "3gh686e3-45c2-447d-b657-b3364da84351",
		"expiresOn":  30,
		"refreshToken": "3ab586d3-45c2-447d-b657-g9768da13730"
	}
}

Response for expired key : (Error) 400

{
    "id": "api.masterkey.create",
    "ver": "v1",
    "ts": "2018-01-29 11:21:31:853+0000",
    "params": {
        "resmsgid": null,
        "msgid": "8e27cbf5-e299-43b0-bca7-8347f7e5abcf",
        "err": "INVALID_KEY",
        "status": "INVALID_KEY",
        "errmsg": "Either he key doesn't exists or it has been expired"
    },
    "responseCode": "CLIENT_ERROR",
    "result": {
        }
}

...