Operations
An operation is a named action, such as kubernetes/get-pods or kubernetes/restart-pod, that Remote Operator runs in a customer's deployment to check or fix something. Operations are grouped into plugins, take typed parameters, and declare a risk tier.
When no operation answers your question, a debug session runs kubectl or a cloud CLI instead.
Run an operation
List the plugins, then invoke an operation the deployment declares:
alien operations list --deployment customer-1/us-east-1
alien operations invoke \
--deployment customer-1/us-east-1 \
--operation kubernetes/get-pods \
--params '{"namespace":"checkout","maxResults":10}'The CLI waits up to 60 seconds for the result (--timeout changes it). An operation from a plugin the deployment's release doesn't declare fails with OPERATIONS_PLUGIN_NOT_DECLARED.
If the operation needs approval, the CLI prints Access is required to run <plugin>/<operation>. and the command to request it. With --json, the result has "status": "pending-approval". Add --request-access to create the request, wait for approval, and run:
alien operations invoke \
--deployment customer-1/us-east-1 \
--operation kubernetes/restart-pod \
--params '{"namespace":"checkout","pod":"api-7c9d"}' \
--request-access --access-duration 1hOperations are not commands. A command calls a handler in your own code with alien commands invoke and has no approval rules. Use an operation when a customer should decide whether it runs.
Risk tiers
| Tier | Meaning | Example |
|---|---|---|
| Read-only | Reads state. Changes nothing. | postgres/locks |
| Mutating | Changes a running system in a bounded, reversible way. | kubernetes/scale |
| Destructive | Can delete or lose data. | Custom plugins only today |
Built-in catalog
Every built-in operation is read-only except kubernetes/restart-pod and kubernetes/scale.
| Plugin | Operations |
|---|---|
kubernetes | get-pods, pod-details, logs, events, workload-status, rollout-status, services-and-endpoints, resource-usage, restart-pod (mutating), scale (mutating) |
postgres | health, version, activity, locks, long-running-queries |
redis | ping, info, slowlog, client-list |
kafka | consumer-lag, topic-describe |
clickhouse | health, running-queries, table-sizes |
elasticsearch | cluster-health, index-stats |
s3 | head-bucket, list-objects, head-object |
sqs | list-queues, queue-stats, redrive-policy |
cloudwatch | query-metrics, alarms, log-groups |
ec2 | instances, instance-status, volumes |
rds | instances, clusters, events |
elbv2 | load-balancers, target-groups, target-health |
aws-vpc | vpcs, subnets, route-tables, security-group-rules |
gcs | list-objects, bucket-usage, object-head |
pubsub | topics, subscriptions, subscription-stats |
gce | instances, disks, instance-groups |
gcp-vpc | networks, subnetworks, routes, firewall-rules |
The dashboard lists the same catalog under Operations → Catalog, with Built-in and Custom sections. Azure resource operations aren't available yet.
Declare operations in alien.ts
A deployment runs only the plugins its release declares. Declare them with .operations() on the stack. Each plugin takes its settings and an approval map:
import * as alien from "@alienplatform/core"
const data = new alien.Storage("data").build()
export default new alien.Stack("acme")
.add(data, "frozen")
.operations({
kubernetes: {
approval: {
"*": "auto",
"restart-pod": "manual",
scale: "manual",
},
},
s3: { buckets: [data] },
cloudwatch: { approval: { "*": "auto" } },
})
.build()This stack:
- runs every Kubernetes read without approval
- requires approval for the two mutating Kubernetes operations
- scopes
s3to thedatabucket;s3has no rule, so its operations need approval - runs CloudWatch reads freely
Approval rules
Alien picks the rule for an operation in this order:
- The exact operation name, without the plugin prefix:
restart-pod, notkubernetes/restart-pod. *.- None. No rule means the operation needs approval.
A rule is "auto" or "manual", or an object with a decision and a maxRisk. Alien reads maxRisk only from the * rule: it's the highest tier a wildcard access request for the plugin can cover. Without it, a wildcard request covers only read-only operations.
This stack takes ClickHouse settings from inputs and lets wildcard requests reach mutating Kubernetes operations:
import * as alien from "@alienplatform/core"
const inputs = alien.inputs({
clickhouseUrl: alien.string({
label: "ClickHouse URL",
description: "The URL of your ClickHouse server",
providedBy: "deployer",
required: true,
}),
clickhousePassword: alien.secret({
label: "ClickHouse password",
description: "Password for the read-only ClickHouse user",
providedBy: "deployer",
required: true,
}),
})
export default new alien.Stack("acme")
.inputs(inputs)
.operations({
clickhouse: {
url: inputs.clickhouseUrl,
password: inputs.clickhousePassword,
database: "default",
approval: { "*": "auto" },
},
kubernetes: {
approval: { "*": { decision: "manual", maxRisk: "mutating" } },
},
plugins: ["acme-admin@1.2.0"],
})
.build()Settings and custom plugins
Plugin settings are a string, a stack input, or stack resources:
- A secret setting must come from an
alien.secretinput. - A resource setting lists resources of the type the plugin needs. The
s3plugin'sbucketssetting takes Storage resources and scopes its object permissions to them.
Custom plugins go under plugins, pinned to an exact published version: "name@version", or { name, version, approval } when the plugin needs settings or rules.
.operations()throws when a string entry has no version, or when it has no plugins at all.- Declare each custom plugin once, and don't give it the name of a built-in plugin the stack also declares.
Release checks
The declaration is part of the release. Changes take effect after alien release, when each deployment updates. Release creation fails if:
- a plugin name isn't built in
- a custom version isn't published in the project
- a setting is missing or invalid
- a rule names an operation the plugin doesn't have
- a
maxRiskisn'tread-only,mutating, ordestructive
Push deployments
A push deployment on AWS or Google Cloud has no Operator. When its release declares .operations(), the release adds an operations Worker (Lambda on AWS, Cloud Run on Google Cloud) that runs the declared plugins in the customer's account.
The customer's initial setup, the one-time step their admin runs, owns the Worker's role. The admin reruns initial setup the first time, and again whenever the plugins' permissions change. Until then, operations fail with OPERATIONS_NOT_ENABLED.
An operation, retries included, must finish within 900 seconds on AWS and 600 seconds on Google Cloud.
For an Operator added to your own Helm chart, declare the same thing in the Helm value remoteOperator.operations. See Add to an existing product.
Build a custom plugin
A custom plugin is a Rust program that exposes your own operations, for example a health check against your application's admin API. Each operation has a name, a risk tier, typed parameters, a typed result, and the permissions it needs.
alien operations init acme-admin # scaffold, with one read-only health operation
cd acme-admin
cargo run --bin generate-metadata # regenerate metadata.json after each change
alien operations check # validate metadata against the typed operations
alien operations test # run cargo test
alien operations permissions --cloud aws # preview the IAM grants, offline
alien operations package # build a Linux binary and zip the bundle
alien operations publish ./acme-admin-0.1.0.zipinit,check,test,permissions,docs, andpackagework offline.packagebuilds for the machine's architecture. Build on each architecture to ship bothamd64andarm64.alien operations check --manifest-onlyvalidates a plugin you don't trust without building it.
Custom plugins need the Enterprise plan.
Each operation is defined once in Rust with OperationDefinition in a TypedOperations registry, and metadata.json is generated from those definitions. check, package, and publish reject metadata that wasn't generated:
| Message | Fix |
|---|---|
'<directory>' has no metadata generator; plugins must generate metadata.json from typed operations. | Add the src/bin/generate-metadata.rs binary that alien operations init creates, and register operations with OperationDefinition. |
generated metadata in '<directory>' is stale or invalid | Run cargo run --bin generate-metadata. |
bundle '<path>' has operations without valid inputSchema and outputSchema objects | Regenerate metadata.json and rebuild with alien operations package. |
To use a published plugin, add "<name>@<version>" to plugins in .operations().
Preview a plugin's permissions
alien operations permissions ./acme-admin --cloud aws --jsonThis prints the grants a plugin's operations declare, using the same compiler as initial setup.
--cloudalso takesgcp,azure, orkubernetes.- Pass the exact resources the installation will allow with repeated
--s3-bucket-arn,--sqs-queue-arn, or--gcs-bucket. A grant that needs a resource list fails without one. - For Kubernetes,
--permission diagnostics(the default) grants reads, and--permission remediationadds the Pod deletion and workload scaling the plugin declares.
The installation, not the plugin, decides namespace or cluster scope.
The custom operations example has a read-only doctor operation and a mutating one that call an application's admin API.
Keep each operation narrow: one question or one repair. Avoid general shells, arbitrary SQL, or an unrestricted Kubernetes proxy, and keep results free of customer records and secrets.
Next
Add to an existing product
Add Remote Operator to a Helm chart or Amazon ECS service you already ship, verify it with a read-only diagnostic, and record the version it runs.
Access requests
Request time-boxed access to operations and debug sessions, see who approves on each platform, and revoke a grant.