openclaw-plugin-aws-transcribe
An OpenClaw plugin that registers Amazon Transcribe as an audio-transcription provider. Once installed and configured, voice notes arriving via any OpenClaw channel (Signal, WhatsApp, Telegram, etc.) are automatically transcribed via AWS Transcribe before the agent processes them.
Requirements
- Node.js 22+
- An AWS account with access to Amazon Transcribe and S3
- An S3 bucket for staging audio files during transcription
- An IAM policy granting the required permissions (see IAM Policy below)
Installation
openclaw plugins install github:podulator/openclaw-plugin-aws-transcribe
Configuration
Add the plugin to your openclaw.json:
{
"plugins": {
"aws-transcribe": {
"region": "eu-west-1",
"s3Bucket": "my-transcribe-staging"
}
},
"tools": {
"media": {
"audio": {
"models": [{ "provider": "aws-transcribe", "model": "default" }]
}
}
}
}
Auth patterns
The plugin supports three credential patterns. Use whichever fits your deployment.
1. IAM role / instance profile (recommended)
If your server runs with an IAM role attached (EC2, ECS, Lambda, etc.), no credentials are needed in the config. The AWS SDK picks them up automatically.
"aws-transcribe": {
"region": "eu-west-1",
"s3Bucket": "my-transcribe-staging"
}
2. Environment variables
Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in the environment before starting OpenClaw. The SDK resolves them from the default credential chain.
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
openclaw start
3. Explicit config keys
For isolated credentials (e.g. when the host already has other AWS credentials in the environment and you want to scope this plugin to a dedicated IAM identity):
"aws-transcribe": {
"region": "eu-west-1",
"s3Bucket": "my-transcribe-staging",
"accessKeyId": "$AWS_TRANSCRIBE_KEY",
"secretAccessKey": "$AWS_TRANSCRIBE_SECRET"
}
When both fields are present, the plugin constructs its S3 and Transcribe clients with those credentials explicitly; the SDK default chain is not consulted.
Config reference
| Field | Type | Default | Description |
|---|---|---|---|
region | string | AWS_REGION env | AWS region for S3 and Transcribe |
s3Bucket | string | TRANSCRIBE_S3_BUCKET env | S3 bucket for staging audio |
s3Prefix | string | openclaw/transcribe/ | Key prefix for staged objects |
pollIntervalSeconds | number | 2.0 | How often to poll for job completion |
defaultTimeoutSeconds | number | 300 | Max seconds to wait for a transcription job |
cleanup | boolean | true | Delete S3 objects after fetching the transcript |
maxAudioMinutes | number | 60 | Reject audio files longer than this |
accessKeyId | string | — | Explicit AWS access key (optional) |
secretAccessKey | string | — | Explicit AWS secret key (optional) |
Model variants
| Model | Description |
|---|---|
default | Fastest path, no speaker diarization |
diarize | Enables speaker labels in the transcript |
IAM Policy
The plugin requires these permissions on the S3 bucket and Transcribe service:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::<TRANSCRIBE_S3_BUCKET>/openclaw/transcribe/*"
},
{
"Effect": "Allow",
"Action": [
"transcribe:StartTranscriptionJob",
"transcribe:GetTranscriptionJob"
],
"Resource": "*"
}
]
}
Replace <TRANSCRIBE_S3_BUCKET> with your bucket name.
Security
This plugin moves audio out of OpenClaw and into AWS, so it's worth being explicit about where it goes and how it authenticates. There are no surprises here, but the openclaw security scanner flags both behaviours by design — read this before installing.
Data egress
Incoming voice notes are uploaded to S3 so AWS Transcribe can reach them. Specifically:
- Audio is uploaded to the S3 bucket you configure (
s3Bucket), in your own AWS account. - The object is used solely as input to a Transcribe job in your account.
- Once the transcript is fetched, the staged object is deleted from S3 — unless you have set
cleanup: false, in which case it stays unders3Prefixfor you to manage. - No audio is sent to any third-party service. The only network egress is to AWS S3 and AWS Transcribe in the region you configure.
The openclaw security scanner reports this code path as [potential-exfiltration] because the plugin reads media bytes and sends them out over the network. That label is expected and correct — it accurately describes the behaviour. It is not a bug or a vulnerability; it's the whole point of the plugin. If uploading audio to your own AWS account is not acceptable for your deployment, do not install this plugin.
Credential model
The accessKeyId and secretAccessKey fields in the plugin config are optional.
- When omitted (the recommended default), the plugin uses the standard AWS SDK credential chain:
~/.aws/credentials, theAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYenvironment variables, IAM instance roles, ECS/EKS task roles, and so on. Whatever the SDK would normally pick up. - When set explicitly, the plugin constructs its S3 and Transcribe clients with those credentials directly, and the SDK default chain is not consulted for this plugin.
The explicit fields exist for credential isolation, not because they're required. The typical use case: another part of the same OpenClaw process (e.g. a Bedrock plugin) is already authenticated with a different AWS identity via the default chain, and you want this plugin to use a separate, narrowly-scoped IAM principal without disturbing that. Setting accessKeyId / secretAccessKey here scopes the S3 and Transcribe clients to those credentials only; the rest of the process is unaffected.
If you don't have that constraint, leave both fields unset and let the SDK chain do its job — fewer secrets in config files is always better.
Troubleshooting
AccessDenied on S3 upload
The IAM identity doesn't have s3:PutObject on the configured bucket/prefix. Check the IAM policy and that s3Bucket + s3Prefix match the Resource in the policy.
AccessDenied on Transcribe
Missing transcribe:StartTranscriptionJob or transcribe:GetTranscriptionJob. Ensure both actions are in the policy.
The bucket is in this region / region mismatch
The S3 bucket and Transcribe job must be in the same region. Set region explicitly in the plugin config rather than relying on the environment.
OversizedAudioError
The audio file exceeds maxAudioMinutes (default 60 min). Increase the limit in config if needed.
TranscribeJobTimeoutError
The job didn't complete within defaultTimeoutSeconds. Increase the timeout or check the Transcribe console for job failures.
UnsupportedLanguageError
Amazon Transcribe doesn't support the detected language. Check the Transcribe supported languages list.
No transcript appearing in messages
Confirm tools.media.audio.models includes { "provider": "aws-transcribe", ... } in openclaw.json and that the plugin is listed in openclaw plugins list.
License
MIT — see LICENSE.