Skip to content

Latest commit

 

History

History

rpc-log-plugin

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

RPC Log Plugin

The rpc-log-plugin records Core Lightning RPC requests as JSON objects in Google Cloud Storage.

It is useful when you need a durable audit trail for debugging, operational analysis, or investigating how a node is being used. The plugin observes selected calls through the rpc_command hook, replaces values of known sensitive fields with "***", and uploads each request as a separate object.

Objects are stored under the following prefix:

rpc/<RFC3339 timestamp>-<UUID>.json

The UUID makes every object name unique, so the plugin never needs to overwrite an existing log.

Security model

The plugin recursively redacts named JSON fields whose keys contain one of the configured sensitive terms, including rune, hsmsecret, preimage, payment_secret, private_key, seed, and mnemonic. Matching is case-insensitive.

This is a defensive filter, not a complete data-loss-prevention system. In particular, positional RPC parameters do not contain field names and therefore cannot be identified by the current sanitizer. Unknown plugin RPCs may also use different names for sensitive values. Review the resulting data before enabling the plugin on a production node.

For least privilege, grant the plugin only the roles/storage.objectCreator role on its bucket. This allows it to create objects but not read, list, delete, or overwrite them. Bucket creation must be performed separately by a deployment or administrator identity.

Build

From the repository root:

cargo build --release --package rpc-log-plugin

The executable is created at:

target/release/rpc-log-plugin

Create the bucket

The following commands must be run with an identity that can create buckets and manage bucket IAM policies:

PROJECT_ID="my-project"
BUCKET="my-cln-rpc-logs"
REGION="europe-west1"
WRITER_SA="cln-log-writer@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud services enable storage.googleapis.com \
  --project="${PROJECT_ID}"

gcloud storage buckets create "gs://${BUCKET}" \
  --project="${PROJECT_ID}" \
  --location="${REGION}" \
  --uniform-bucket-level-access

gcloud storage buckets add-iam-policy-binding "gs://${BUCKET}" \
  --member="serviceAccount:${WRITER_SA}" \
  --role="roles/storage.objectCreator"

Bucket names are globally unique. Choose a different value if the requested name is already taken.

The plugin accepts the plain bucket ID through log-bucket, for example my-cln-rpc-logs. Do not pass gs:// or the full projects/_/buckets/... resource name; the plugin adds the resource-name prefix internally.

Authentication

The Google Cloud client uses Application Default Credentials (ADC). No credential path is configured in the plugin.

GKE

Use Workload Identity Federation for GKE and associate the pod's Kubernetes service account with the Google service account that received roles/storage.objectCreator. The pod then obtains short-lived credentials automatically; do not mount a downloaded service-account key in the container.

Local development

Authenticate ADC with the Google Cloud CLI:

gcloud auth application-default login

The authenticated development identity must have permission to create objects in the selected bucket.

Configure Core Lightning

Add the plugin and bucket ID to lightningd's configuration:

plugin=/absolute/path/to/target/release/rpc-log-plugin
log-bucket=my-cln-rpc-logs
log-rpc-list=checkrune,commando,pay

Alternatively, pass the same options on the command line:

lightningd \
  --plugin=/absolute/path/to/target/release/rpc-log-plugin \
  --log-bucket=my-cln-rpc-logs \
  --log-rpc-list=checkrune,commando,pay

The bucket must already exist when RPC requests are logged. Authentication failures, missing buckets, and upload errors are returned by the hook, so verify the setup outside production before relying on it.

Select RPC methods

log-rpc-list controls which RPC methods are logged. The default is checkrune. Use a comma-separated list to select more than one method:

log-rpc-list=checkrune,commando,pay

Whitespace around method names is ignored. Method names must otherwise match exactly. Calls to methods not present in this list continue normally without being uploaded.

Log format

Each uploaded object contains one JSON document:

{
  "method": "pay",
  "request_id": 42,
  "body": {
    "bolt11": "lnbc...",
    "payment_secret": "***"
  },
  "caller": "Name",
  "peer_id": "02..."
}

The caller field contains the value of the first operator#<name> comment found in a rune passed through named JSON parameters. The caller field exists only if the request has rune, the rune can be decoded and has such tag.

Create a rune carrying this comment with:

lightning-cli createrune -k restrictions='[["operator#Name"]]'

When that rune is supplied as a named rune parameter, the plugin records "Name" in caller and redacts the rune itself from body. The comment is descriptive metadata and does not restrict authorization.

The request body may still contain financially or personally sensitive information that is not covered by the danger field list, such as invoices, labels, descriptions, addresses, routes, and payment hashes. Restrict access to the bucket and configure retention and deletion policies appropriate for your environment.