diff --git a/src/content/docs/ai-gateway/observability/logging/logpush.mdx b/src/content/docs/ai-gateway/observability/logging/logpush.mdx
index c4a89c2a5cb788..82b7efd3854720 100644
--- a/src/content/docs/ai-gateway/observability/logging/logpush.mdx
+++ b/src/content/docs/ai-gateway/observability/logging/logpush.mdx
@@ -6,7 +6,7 @@ sidebar:
text: Beta
---
-import { Render } from "~/components";
+import { Render, Tabs, TabItem } from "~/components";
AI Gateway allows you to securely export logs to an external storage location, where you can decrypt and process them.
You can toggle Logpush on and off in the [Cloudflare dashboard](https://dash.cloudflare.com) settings.
@@ -37,7 +37,9 @@ To configure Logpush for AI Gateway, follow these steps:
## 1. Generate an RSA key pair locally
-You need to generate a key pair to encrypt and decrypt the logs. This script will output your RSA privateKey and publicKey. Keep the private key secure, as it will be used to decrypt the logs. Below is a sample script to generate the keys using Node.js.
+You need to generate a key pair to encrypt and decrypt the logs. This script will output your RSA privateKey and publicKey. Keep the private key secure, as it will be used to decrypt the logs. Below is a sample script to generate the keys using Node.js and OpenSSL.
+
+
```js title="JavaScript"
const crypto = require("crypto");
@@ -64,6 +66,23 @@ Run the script by executing the below code on your terminal. Replace `file name`
node {file name}
```
+
+
+1. Generate private key:
+ Use the following command to generate a RSA private key:
+
+ ```bash
+ openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:4096
+ ```
+
+2. Generate public key:
+ After generating the private key, you can extract the corresponding public key using:
+
+ ```bash
+ openssl rsa -pubout -in private_key.pem -out public_key.pem
+ ```
+
+
## 2. Upload public key to gateway settings
@@ -79,6 +98,10 @@ After configuring Logpush, logs will be sent encrypted using the public key you
## 5. Decrypt logs
+To decrypt the encrypted log bodies and metadata from AI Gateway, you can use the following Node.js script or OpenSSL:
+
+
+
To decrypt the encrypted log bodies and metadata from AI Gateway, download the logs to a folder, in this case its named `my_log.log.gz`.
Then copy this javascript file into the same folder and place your private key in the top variable.
@@ -96,81 +119,81 @@ const zlib = require("zlib");
const readline = require("readline");
async function importAESGCMKey(keyBuffer) {
- try {
- // Ensure the key length is valid for AES
- if ([128, 192, 256].includes(256)) {
- return await crypto.webcrypto.subtle.importKey(
- 'raw',
- keyBuffer,
- {
- name: 'AES-GCM',
- length: 256
- },
- true, // Whether the key is extractable (true in this case to allow for export later if needed)
- ['encrypt', 'decrypt'] // Use for encryption and decryption
- );
- } else {
- throw new Error('Invalid AES key length. Must be 128, 12, or 256 bits.');
- }
- } catch (error) {
- console.error('Failed to import key:', error);
- throw error;
- }
+ try {
+ // Ensure the key length is valid for AES
+ if ([128, 192, 256].includes(256)) {
+ return await crypto.webcrypto.subtle.importKey(
+ "raw",
+ keyBuffer,
+ {
+ name: "AES-GCM",
+ length: 256,
+ },
+ true, // Whether the key is extractable (true in this case to allow for export later if needed)
+ ["encrypt", "decrypt"], // Use for encryption and decryption
+ );
+ } else {
+ throw new Error("Invalid AES key length. Must be 128, 12, or 256 bits.");
+ }
+ } catch (error) {
+ console.error("Failed to import key:", error);
+ throw error;
+ }
}
async function decryptData(encryptedData, aesKey, iv) {
- const decryptedData = await crypto.subtle.decrypt(
- {name: "AES-GCM", iv: iv},
- aesKey,
- encryptedData
- );
- return new TextDecoder().decode(decryptedData);
+ const decryptedData = await crypto.subtle.decrypt(
+ { name: "AES-GCM", iv: iv },
+ aesKey,
+ encryptedData,
+ );
+ return new TextDecoder().decode(decryptedData);
}
async function decryptBase64(privateKey, data) {
- if (data.key === undefined) {
- return data
- }
-
- const aesKeyBuf = crypto.privateDecrypt(
- {
- key: privateKey,
- oaepHash: "SHA256",
- },
- Buffer.from(data.key, "base64"),
- );
- const aesKey = await importAESGCMKey(aesKeyBuf)
-
- const decryptedData = await decryptData(
- Buffer.from(data.data, "base64"),
- aesKey,
- Buffer.from(data.iv, "base64")
- )
-
- return decryptedData.toString();
+ if (data.key === undefined) {
+ return data;
+ }
+
+ const aesKeyBuf = crypto.privateDecrypt(
+ {
+ key: privateKey,
+ oaepHash: "SHA256",
+ },
+ Buffer.from(data.key, "base64"),
+ );
+ const aesKey = await importAESGCMKey(aesKeyBuf);
+
+ const decryptedData = await decryptData(
+ Buffer.from(data.data, "base64"),
+ aesKey,
+ Buffer.from(data.iv, "base64"),
+ );
+
+ return decryptedData.toString();
}
async function run() {
- let lineReader = readline.createInterface({
- input: fs.createReadStream("my_log.log.gz").pipe(zlib.createGunzip()),
- });
-
- lineReader.on("line", async (line) => {
- line = JSON.parse(line);
-
- const {Metadata, RequestBody, ResponseBody, ...remaining} = line;
-
- console.log({
- ...remaining,
- Metadata: await decryptBase64(privateKey, Metadata),
- RequestBody: await decryptBase64(privateKey, RequestBody),
- ResponseBody: await decryptBase64(privateKey, ResponseBody),
- });
- console.log("--");
- });
+ let lineReader = readline.createInterface({
+ input: fs.createReadStream("my_log.log.gz").pipe(zlib.createGunzip()),
+ });
+
+ lineReader.on("line", async (line) => {
+ line = JSON.parse(line);
+
+ const { Metadata, RequestBody, ResponseBody, ...remaining } = line;
+
+ console.log({
+ ...remaining,
+ Metadata: await decryptBase64(privateKey, Metadata),
+ RequestBody: await decryptBase64(privateKey, RequestBody),
+ ResponseBody: await decryptBase64(privateKey, ResponseBody),
+ });
+ console.log("--");
+ });
}
-run()
+run();
```
Run the script by executing the below code on your terminal. Replace `file name` with the name of your JavaScript file.
@@ -179,7 +202,33 @@ Run the script by executing the below code on your terminal. Replace `file name`
node {file name}
```
-## Script Explanation
-
The script reads the encrypted log file `(my_log.log.gz)`, decrypts the metadata, request body, and response body, and prints the decrypted data.
Ensure you replace the `privateKey` variable with your actual private RSA key that you generated in step 1.
+
+
+
+1. Decrypt the encrypted log file using the private key.
+
+Assuming that the logs were encrypted with the public key (for example `public_key.pem`), you can use the private key (`private_key.pem`) to decrypt the log file.
+
+For example, if the encrypted logs are in a file named `encrypted_logs.bin`, you can decrypt it like this:
+
+```bash
+openssl rsautl -decrypt -inkey private_key.pem -in encrypted_logs.bin -out decrypted_logs.txt
+```
+
+- `-decrypt` tells OpenSSL that we want to decrypt the file.
+- `-inkey private_key.pem` specifies the private key that will be used to decrypt the logs.
+- `-in encrypted_logs.bin` is the encrypted log file.
+- `-out decrypted_logs.txt`decrypted logs will be saved into this file.
+
+2. View the decrypted logs
+ Once decrypted, you can view the logs by simply running:
+
+```bash
+cat decrypted_logs.txt
+```
+
+This command will output the decrypted logs to the terminal.
+
+