I had a similar requirement, to keep Kong and Azure in sync with respect to x5c and so on.
Because Azure rotate (lazy rotate) keys every so often it had to be a script that keeps the keys in sync, so I wrote a python script.
Now I don’t think this is what you are looking for, but it might be useful to others, so apologies if I am distracting your ticket, but since its related, I will paste the script here.
import json
import requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.x509 import load_pem_x509_certificate
PEMSTART = "-----BEGIN CERTIFICATE-----\n"
PEMEND = "\n-----END CERTIFICATE-----\n"
kongURL = 'https://api.kong.myapp.com'
username = 'admin'
password = 'password'
tenantID = '121212-12121-1212121-121212'
azureURL = 'https://login.microsoftonline.com/'+tenantID+'/discovery/keys'
class JWT:
def __init__(self, algorithm, key, rsa_public_key):
self.algorithm = algorithm
self.key = key
self.rsa_public_key = rsa_public_key
f = open("azure-apps.txt", "r")
for app in f:
print("Processing App: " + app)
# Get the consumer definitions from Kong
consumerResponse = requests.get(kongURL+'/'+app.strip(), auth=(username, password))
consumer = consumerResponse.json()
appId = consumer['custom_id']
consumerId = consumer['id']
print('App ID: ' + appId)
print('Consumer ID: ' + consumerId)
# Get the consumer JWT details from Kong
jwtResponse = requests.get(kongURL+'/'+consumerId+'/jwt', auth=(username, password))
jwt = jwtResponse.json()
kongKeys = list()
for i in jwt['data']:
key = i['key']
if key:
kongKeys.append(key)
#print(kongKeys)
# Get the keys/cert details from Azure
azureResponse = requests.get(azureURL + "?appid=" + appId)
azure = azureResponse.json()
azureKeys = list()
for i in azure['keys']:
key = i['kid']
if key:
azureKeys.append(key)
#print(azureKeys)
# These are keys present in Azure but not in Kong
keysToBeAdded = set(azureKeys) - set(kongKeys)
print('Keys to be added: ' + ','.join(keysToBeAdded))
# These are keys present in Kong but not in Azure
keysToBeDeleted = set(kongKeys) - set(azureKeys)
print('Keys to be deleted: ' + ','.join(keysToBeDeleted))
# Add missing keys to Kong
for key in keysToBeAdded:
for i in azure['keys']:
azureKey = i['kid']
if azureKey == key:
# Get the x509 cert and convert that to a PEM
rawcert = ''.join(i['x5c'])
cert_str = PEMSTART + rawcert + PEMEND
#print(cert_str)
cert_obj = load_pem_x509_certificate(cert_str.encode('ascii'), default_backend())
pem = cert_obj.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)
#print(pem)
# Prepare jwt request to be sent to Kong
dataObj = JWT('RS256', key, pem)
data = json.dumps(dataObj.__dict__)
#print(data)
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
response = requests.post(kongURL + '/' + consumerId + '/jwt', data=data, auth=(username, password), headers=headers)
#print(response)
if response.status_code == 201:
print('Key ' + key + ' has been added to Kong')
else:
print('There was a problem adding key '+ key +' to Kong')
# Delete redundant keys from Kong
for key in keysToBeDeleted:
response = requests.delete(kongURL+'/'+consumerId+'/jwt/' + key, auth=(username, password))
#print(response)
if response.status_code == 204:
print('Key ' + key + ' has been deleted from Kong')
else:
print('There was a problem deleting key '+ key +' from Kong')
It will require an azure-apps.txt that contains the names of Azure apps. I use the custom_id to store the Azure App ID