# Upstash Redis plugin

The Upstash Redis plugin lets a Vaubaan Gateway mission use Upstash Redis without handing the agent a credential. Serverless Redis plane — databases through the Management API, key-value data through each database REST endpoint.

- Version: `3.0.0` (package `@vaubaan/plugin-upstash-redis`)
- Status: stable
- Health: not enough reports yet — [what this means](/plugins/health)
- Source: [plugins/upstash-redis](https://github.com/vaubaan/gateway/tree/main/plugins/upstash-redis), catalog [risk-catalog.yaml](https://github.com/vaubaan/gateway/blob/main/plugins/upstash-redis/src/risk-catalog.yaml) version 6 of 2026-10-14
- How to connect an account: [Connect Upstash Redis](/docs/providers/upstash-redis)
- How it is modelled: [handbook](https://github.com/vaubaan/gateway/blob/main/docs/handbook/providers/upstash-redis.md)

One account is one Upstash account (email and management API key); one resource is one Redis database. Its owner labels each database with an environment; key reads and writes, deletions, FLUSH, arbitrary commands and database management are separate permissions held per label.

## Permissions

Each permission is a named risk of the plugin's catalog: a mission holds an explicit list of them, never "all". The severity is computed from the permission's six axes (undo, blast radius, data, cost, visible to, lasts); nothing is decided from it.

| Permission | What it allows | Severity | Why it is a risk |
| --- | --- | --- | --- |
| `upstash-redis.read-database-metadata` | Read database list / details / stats (Management API reads) | low | Inventory of databases, their configuration, endpoints, and usage statistics. Surface of attack is negligible : metadata only, no data or credential leaks (\`execute\` strips the REST tokens from the Management API answers). This permission is the always-on baseline ; every read of the service needs it. |
| `upstash-redis.read-data` | Read Redis data (GET, KEYS, SCAN, HGETALL, LRANGE, SMEMBERS, TTL, DBSIZE) | low | Read operations on the key-value data stored in a database. May expose application secrets if stored in Redis (session tokens, cached credentials). Standard posture for a coding agent in debug mode. |
| `upstash-redis.write-data` | Write Redis data (SET, HSET, LPUSH, SADD — without a time to live) | low (only for `development`, `staging`, `prod`) | Create, overwrite or modify individual keys, through the dedicated tools or the generic \`execute\` tool. An overwrite replaces the previous value, which is lost unless it is kept elsewhere ; a RENAME replaces the destination key. Affects application state if the app reads from Redis at runtime. The deletion commands (DEL, UNLINK, the POP and REM families), every command that sets a time to live (EXPIRE, SETEX, SET … EX) or moves data out of a key (RENAME, LMOVE, SMOVE), FLUSH and arbitrary commands need it next to their own, more severe permission, so a mission holding \`write-data\` alone cannot run them : it can write and overwrite values that stay, nothing else. |
| `upstash-redis.delete-data` | Delete keys, fields, members or entries — now, or by a time to live or a move (DEL, UNLINK, HDEL, LPOP, EXPIRE, SET … EX, RENAME) | low (only for `development`, `staging`, `prod`) | Targeted removal of data : whole keys (DEL, UNLINK, GETDEL), parts of a value (HDEL, LPOP, SREM, ZREM, XTRIM…), any time to live given to a key or a field (EXPIRE, PEXPIRE, SETEX, SET with EX or PX, the absolute expiries) — the data is gone when it elapses, and one second is a deletion in all but name —, and the moves (RENAME, LMOVE, SMOVE, RPOPLPUSH), which take a key or an element out of its source. Through the dedicated \`del\`, \`expire\` and \`set\` tools or the generic \`execute\` tool. Costly to reverse if the data is not backed up elsewhere. May break application state. A cache write with a time to live therefore needs this permission next to \`write-data\`. |
| `upstash-redis.flush-database` | FLUSHDB / FLUSHALL — mass data deletion via the execute tool | high (only for `development`, `staging`, `prod`) | FLUSHDB / FLUSHALL wipes all keys in the database. Irreversible without a backup. Only reachable via the generic \`execute\` tool (not exposed as a dedicated tool). Presets ask first outside development. |
| `upstash-redis.execute-arbitrary` | Generic execute — scripts, administration and any uncategorized Redis command | medium (only for `development`, `staging`, `prod`) | The \`execute\` tool can run any Redis command. A command that is not a known read, write, deletion or flush falls into this catch-all : scripts and functions (EVAL, FCALL), server administration (CONFIG, ACL), transaction control, and any command the gateway does not know or cannot read. A script can delete or flush the database, so holding this permission allows everything a Redis command can do. Presets ask first outside development. |
| `upstash-redis.create-database` | Create a new database (Management API) | medium | Creates a new Redis database in the Upstash account. Reversible (can delete it). May incur costs if the account has a paid plan. Account-rooted : the new database is not a mission resource yet. |
| `upstash-redis.delete-database` | Delete an entire database (Management API) | high (only for `development`, `staging`, `prod`) | Permanently deletes a Redis database and all its data. Irreversible without a backup. Equivalent to dropping a production data store. Presets ask first in every environment. |
| `upstash-redis.modify-database` | Rename database (Management API) | medium (only for `development`, `staging`, `prod`) | Modifies database metadata (currently: rename). Rename can break any downstream reference that uses the old name. Classified as credentials touch because it affects the database identity. Presets ask first in every environment (configuration change). |
| `upstash-redis.read-stats` | Read usage statistics | low | Read-only access to database usage statistics (commands processed, memory usage, throughput). No data or credential exposure. |
| `upstash-redis.uncategorized-write` | Uncategorized Upstash Redis write | medium (only for `development`, `staging`, `prod`; the catch-all: touched only by a call no other permission covers) | Catch-all for writes that have not been explicitly categorised. If observed in production, signals that a tool was added without a matching catalog entry — the mission creator must opt in explicitly (no implicit accept). Never carried by a preset. |

## Presets

A preset pre-fills the permissions of a mission for one account, with a limit per period, a rate and whether each permission runs freely or asks the mission creator first. The person creating the mission adjusts it; the mission stores the explicit list.

### Read-only

`read-only` — Inspect databases, usage statistics and key-value data on the selected databases; no write.

| Permission | What it allows | Limit per period | Rate | Runs |
| --- | --- | --- | --- | --- |
| `upstash-redis.read-database-metadata` | Read database list / details / stats (Management API reads) | 2000 | 120 per minute | runs freely |
| `upstash-redis.read-stats` | Read usage statistics | 500 | 30 per minute | runs freely |
| `upstash-redis.read-data` | Read Redis data (GET, KEYS, SCAN, HGETALL, LRANGE, SMEMBERS, TTL, DBSIZE) | 5000 | 120 per minute | runs freely |

### Developer

`developer` — Key-level reads and writes (with TTL) and targeted deletions on development and staging databases; no FLUSH, no arbitrary command, no database management.

| Permission | What it allows | Limit per period | Rate | Runs |
| --- | --- | --- | --- | --- |
| `upstash-redis.read-database-metadata` | Read database list / details / stats (Management API reads) | 5000 | 120 per minute | runs freely |
| `upstash-redis.read-stats` | Read usage statistics | 1000 | 60 per minute | runs freely |
| `upstash-redis.read-data` | Read Redis data (GET, KEYS, SCAN, HGETALL, LRANGE, SMEMBERS, TTL, DBSIZE) | 10000 | 120 per minute | runs freely |
| `upstash-redis[development].write-data` |  | 5000 | 120 per minute | runs freely |
| `upstash-redis[staging].write-data` |  | 2000 | 60 per minute | runs freely |
| `upstash-redis[development].delete-data` |  | 1000 | 60 per minute | runs freely |
| `upstash-redis[staging].delete-data` |  | 500 | 30 per minute | runs freely |

### Operator

`operator` — Everything a developer can do plus production key writes, FLUSH, arbitrary commands and database management — production deletions, FLUSH and arbitrary commands outside development, every database deletion and every configuration change asking first.

| Permission | What it allows | Limit per period | Rate | Runs |
| --- | --- | --- | --- | --- |
| `upstash-redis.read-database-metadata` | Read database list / details / stats (Management API reads) | 5000 | 120 per minute | runs freely |
| `upstash-redis.read-stats` | Read usage statistics | 1000 | 60 per minute | runs freely |
| `upstash-redis.read-data` | Read Redis data (GET, KEYS, SCAN, HGETALL, LRANGE, SMEMBERS, TTL, DBSIZE) | 10000 | 120 per minute | runs freely |
| `upstash-redis[development].write-data` |  | 5000 | 120 per minute | runs freely |
| `upstash-redis[staging].write-data` |  | 2000 | 60 per minute | runs freely |
| `upstash-redis[prod].write-data` |  | 500 | 30 per minute | runs freely |
| `upstash-redis[development].delete-data` |  | 1000 | 60 per minute | runs freely |
| `upstash-redis[staging].delete-data` |  | 500 | 30 per minute | runs freely |
| `upstash-redis[prod].delete-data` |  | 100 | 10 per minute | ask me first |
| `upstash-redis[development].flush-database` |  | 50 | 5 per minute | runs freely |
| `upstash-redis[staging].flush-database` |  | 20 | 2 per minute | ask me first |
| `upstash-redis[prod].flush-database` |  | 5 | 1 per minute | ask me first |
| `upstash-redis[development].execute-arbitrary` |  | 500 | 30 per minute | runs freely |
| `upstash-redis[staging].execute-arbitrary` |  | 200 | 20 per minute | ask me first |
| `upstash-redis[prod].execute-arbitrary` |  | 50 | 5 per minute | ask me first |
| `upstash-redis.create-database` | Create a new database (Management API) | 10 | 2 per minute | runs freely |
| `upstash-redis[development].delete-database` |  | 5 | 1 per minute | ask me first |
| `upstash-redis[staging].delete-database` |  | 5 | 1 per minute | ask me first |
| `upstash-redis[prod].delete-database` |  | 2 | 1 per minute | ask me first |
| `upstash-redis[development].modify-database` |  | 10 | 2 per minute | ask me first |
| `upstash-redis[staging].modify-database` |  | 10 | 2 per minute | ask me first |
| `upstash-redis[prod].modify-database` |  | 5 | 1 per minute | ask me first |

## Tools

| Tool | What it does |
| --- | --- |
| `upstash_redis__list_databases` | List databases |
| `upstash_redis__get_database` | Read a database |
| `upstash_redis__create_database` | Create a database |
| `upstash_redis__delete_database` | Delete a database |
| `upstash_redis__rename_database` | Rename a database |
| `upstash_redis__get_database_stats` | Read the usage of a database |
| `upstash_redis__execute` | Run a Redis command |
| `upstash_redis__get` | Read a key |
| `upstash_redis__set` | Set a key |
| `upstash_redis__del` | Delete keys |
| `upstash_redis__keys` | Find keys by pattern |
| `upstash_redis__scan` | Scan the keys |
| `upstash_redis__ttl` | Read the time to live of a key |
| `upstash_redis__expire` | Set the expiry of a key |
| `upstash_redis__hset` | Set fields of a hash |
| `upstash_redis__hgetall` | Read a hash |
| `upstash_redis__lpush` | Prepend values to a list |
| `upstash_redis__lrange` | Read a range of a list |
| `upstash_redis__sadd` | Add members to a set |
| `upstash_redis__smembers` | Read the members of a set |
| `upstash_redis__dbsize` | Count the keys of a database |

## Health

Health: not enough reports yet. A plugin version is deemed validated by the community with at least 200 reports and 90 % of them successful, over the last 90 days, as reported by the instances whose operators turned community telemetry on. It is a community signal, not a security guarantee.
