Automated API Key Rotation/Generation for Some APP ID to Prevent Unauthorized Transactions and Protect Service Payments.
Automated API Key Rotation/Generation for Some APP ID to Prevent Unauthorized Transactions and Protect Service Payments.
Issue: As is well known, APIКeys are used in browsers in an exposed form within URL requests, making them susceptible to being copied by third parties and used for their own purposes.
To mitigate this issue, it's essential to regularly use newly generated API keys while simultaneously revoking the old ones.
This can be done manually by generating API keys through the UI on https://platform.here.com/admin/apps, but this process requires dedicating human resources.
How to Automate API Key Rotation/Generation for Some APP ID?
You can utilize the Identity and Access Management Authentication API v1.1, available on https://www.here.com/docs/bundle/identity-and-access-management-authentication-api-v1.1-api-reference/page/index.html#tag/Application-API-Key-Management.
Step by step regarding above documentation (if you want get out of the box binary or precompiled tool see please attachments at the bottom of this document)
1. Create a separate APP ID that will serve as the master APP ID for the target APP ID (for which you want to rotate/generate API keys) using the UI at https://platform.here.com/admin/apps.
2. Create OAuth 2.0 credential the master APP ID and download this credentials file using the same above UI.
3. Open (in the same UI) your target APP ID, click on the 'Access and Permissions' button, and share your target APP ID with the master APP ID.
The three steps mentioned above only need to be completed once.
The code example below demonstrates how to retrieve the target APP ID, obtain a list of its API keys, delete an old API key, and create a new one.<br />type PlatformApi* = ref object api*: string version*: string baseURL*: stringtype PlatformApps* = ref object total*: int limit*: int items*: seq[PlatformApp] PlatformApp* = ref object id*, hrn*, realm*: string name*, status*, applicationType*: string createdTime*: int appCreationEnabled*, deviceTokenCreationEnabled*: booltype AppApiKeys* = ref object total*, limit*: int items*: seq[AppApiKey] AppApiKey* = ref object apiKeyId*, apiKey*, identity*, realm*, name*: string enabled*: bool createdTime*: int expiresAt*: inttype ResponseToken* = ref object accessToken*, token_type*: string expiresIn*: int<br /><br />const lookupEndpoint = "https://api-lookup.data.api.platform.here.com/lookup/v1/platform/apis"var rotatedAppId: stringvar credTxt: stringvar baseUrl: stringvar hrnAppId: stringvar totalKeys: intvar apiKeys: AppApiKeysvar newKey, oldKey: AppApiKeyvar onlyShowApiKeys = falseproc getApiBaseUrl(apis: string): string = let apis = apis.fromJson(seq[PlatformApi]) for api in apis: if api.api == "authentication" and api.version == "v1.1": return api.baseURLproc getHrnAppId(res: string): string = let apps = res.fromJson(PlatformApps) for app in apps.items: if app.id == rotatedAppId: hrnAppId = app.hrn return hrnAppIdproc checkOldNewKeys() = if totalKeys == 2: if apiKeys.items[0].createdTime > apiKeys.items[1].createdTime: newKey = apiKeys.items[0] oldKey = apiKeys.items[1] else: newKey = apiKeys.items[1] oldKey = apiKeys.items[0] elif totalKeys == 1: newKey = apiKeys.items[0]proc bodyForNewKey(): string = let oldApiKeyId = if not oldKey.isNil: "; deleted apikey was:" & oldKey.apiKeyId else: "" let bdy = %*{ "name": "fromApiGenerated" & oldApiKeyId } $bdy<br /><br /> #Assume you have generated a Bearer 'accessToken' using the OAuth 2.0 credentials of the master APP ID. var client = newHttpClient() #get lookupAPI client.headers = newHttpHeaders([( "Authorization", fmt"Bearer {accessToken}" )]) try: let res = client.getContent(lookupEndpoint) baseUrl = res.getApiBaseUrl finally: client.close() #Get apps & choose rotatedAppId #https://www.here.com/docs/bundle/identity-and-access-management-authentication-api-v1.1-api-reference/page/index.html#tag/Application-Management/operation/listApplications try: let res = client.getContent(fmt"{baseUrl}/apps") hrnAppId = res.getHrnAppId finally: client.close() #Get apikeys of rotatedAppId #https://www.here.com/docs/bundle/identity-and-access-management-authentication-api-v1.1-api-reference/page/index.html#tag/Application-API-Key-Management/operation/getAPIKeys let hrnAppIdEnc = hrnAppId.encodeUrl try: let res = client.getContent(fmt"{baseUrl}/apps/{hrnAppIdEnc}/apiKeys") apiKeys = res.fromJson(AppApiKeys) totalKeys = apiKeys.total finally: client.close() checkOldNewKeys() if onlyShowApiKeys: procOutput() quit(0) if totalKeys == 2: # Delete last apikey of rotatedAppId #https://www.here.com/docs/bundle/identity-and-access-management-authentication-api-v1.1-api-reference/page/index.html#tag/Application-API-Key-Management/operation/deleteAPIKey try: let hrnApiKeyEnc = oldKey.apiKey.encodeUrl let res = client.delete(fmt"{baseUrl}/apps/{hrnAppIdEnc}/apiKeys/{hrnApiKeyEnc}") finally: client.close() # Create new apikey of rotatedAppId #https://www.here.com/docs/bundle/identity-and-access-management-authentication-api-v1.1-api-reference/page/index.html#tag/Application-API-Key-Management/operation/generateAPIKey try: client.headers = newHttpHeaders([ ( "Authorization", fmt"Bearer {accessToken}" ), ( "content-type", "application/json" ) ], true) let bdy = bodyForNewKey() let res = client.post(fmt"{baseUrl}/apps/{hrnAppIdEnc}/apiKeys", body = bdy) let createdKeyRes = (res.bodyStream.readAll()).fromJson(AppApiKey) procOutput(createdKeyRes) finally: client.close()<br />
Here are some pre-built tools compiled from the code above. You can use them directly on your servers:
1. NodeJs: apikeyRotate.min.js<br />node apikeyRotate.min.js --cmd:show --appid:your_target_appid --cred:"$(cat cred.txt)"<br />
or<br />node apikeyRotate.min.js --cmd:rotate! --appid:your_target_appid --cred:"$(cat cred.txt)"<br />
where cred.txt is downloaded OAuth 2.0 credential of the master APP ID
2.
Arm64 MacOS, Arm64 Linux, i386 Linux, amd64 Linux (see attachments)
to compile on your target OS run compile_apikeyRotate.sh
After compile you can run it similar like for NodeJs:<br />apikeyRotate --cmd:rotate! --appid:your_target_appid --cred:cred.txt<br />
where cred.txt is path to file downloaded OAuth 2.0 credential of the master APP ID