aws-sst-development — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited aws-sst-development (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
SST v4 (the "Ion" engine) is a Pulumi-backed IaC framework: you describe AWS resources in TypeScript and SST/Pulumi reconciles them into your account. It gives you high-level sst.aws.* components (Function, Bucket, Dynamo, Cron, Service, …) that expand into many underlying resources, plus an escape hatch to any raw Pulumi aws.* resource for the long tail. This skill encodes a production-proven way to author, link, test, deploy, and troubleshoot SST stacks on AWS — distilled from real multi-stack projects that have paid for each lesson with a prod incident.
SST and Pulumi are third-party — verify current syntax with Context7 (resolve-library-id → query-docs for sst or pulumi-aws) when you're unsure about a component's options. Verify AWS-side facts (service limits, model IDs, IAM action names, region availability) with the AWS docs MCP, never from memory. The patterns here are the how; the docs are the what.
Figure out which mode you're in and jump to the right reference:
| Situation | Go to |
|---|---|
| New project, or adding a resource/module to an existing SST app | Author → references/authoring.md |
| Wiring one module's output into another (links, SSM, IAM scope) | Author → references/authoring.md § Sharing |
| Writing tests for infra so changes don't silently break | Test → references/testing.md |
| Running a deploy, or a deploy just failed | Deploy/Operate → references/deploy-and-troubleshoot.md |
| Migrating a resource between Pulumi types, renaming a physical name | Deploy/Operate → references/deploy-and-troubleshoot.md § Migrations |
Always read the relevant reference before editing — they carry the why behind each rule, which matters more than the rule itself.
SST projects are conventional but not identical. Before editing, build a quick map so your change matches the house style instead of fighting it:
home, providers/region, defaultTags,any global $transform (Node runtime pin, bundle fixups), and the order in which run() imports infra/ modules. The import order is the dependency order; respect it.
This is where resources are declared. Check for an infra/CLAUDE.md — these projects keep IaC-specific rules there, and it's the single most valuable file to read first.
invariants. If they exist, your change must keep them green and probably needs a new assertion.
and the sst/pulumi versions actually installed.
Run npx sst version to confirm you're on v4/Ion (the $config + .sst/platform/ signature). v2/v3 ("SST Classic", CDK-based) is a different framework — these patterns don't apply there.
The projects this skill is built from share a deliberate house style. Some of it is universal (true for any SST v4 + AWS project — apply it everywhere); some is project-specific (a sensible default these projects chose — adopt it for consistency, but recognize a project may differ).
Universal — these principles hold for any SST v4 + AWS project:
whatever the installed SST happens to default to. The idiom is a single global $transform(sst.aws.Function, (args) => { args.runtime ??= "nodejs24.x" }) in run() — ??= is correct here (the transform runs before the component applies its own default, so it fills in only when the user didn't set one). Recent SST already defaults to a current Node runtime, so check the installed default first (Context7); the transform is then version-independence insurance so a future SST downgrade can't silently move your fleet. See references/authoring.md.
Use $interpolate (or pulumi.interpolate). A bare top-level ` ${bucket.arn}/` `` stringifies the `Output` to a `[Output<T>]` placeholder and produces a broken ARN that only fails at deploy time (it type-checks and `sst dev` runs fine). The fix is `$interpolate``` `${bucket.arn}/ . This has caused prod deploy outages. See references/authoring.md` § Outputs.
Pulumi creates-before-destroys, so for a uniqueness-constrained AWS name (bucket, IAM role, gateway) the old resource still owns it and the create fails with ConflictException. Two sequential deploys (teardown, then recreate) is the conservative default; aliases: / pulumi import / state surgery can bridge identity in some cases but only with a reviewed plan. See references/deploy-and-troubleshoot.md § Migrations.
/ aws.*` resources over theaws.cloudcontrol.Resource escape hatch.** CloudControl outputs are stringly-typed and oneOf fields don't patch cleanly. Use it only when no typed resource exists yet, and migrate off it when one ships.
Project-specific defaults — adopt for consistency, but confirm per repo:
home: "aws", and defaultTags carryingProject / Stage / ManagedBy: "sst".
removal: stage === "prod" ? "retain" : "remove"and protect: stage === "prod" so prod resources survive a stack tear-down and non-prod previews clean up.
/{app}/{stage}/{domain}/... prefix — for consumers that aren't in the Pulumi graph (CI scripts, sibling apps, operators). For same-app Lambdas, prefer SST link: (it wires a real dependency edge and grants IAM); don't route same-app sharing through SSM. See references/authoring.md § Sharing.
sst devhot-reload stays light. (For testing, a module export still runs its top-level new sst.aws.* unless it's wrapped in a factory function — see references/testing.md for how to test infra.)
house-style regression net asserting on the source text (resource names, index shapes, IAM scopes). It's a deliberate choice, not an SST limit: Pulumi does support runtime mocks (@pulumi/pulumi/runtime) for behavioral graph tests when a module has real logic. Source assertions don't replace a preview-deploy + smoke test. See references/testing.md.
structured logging before merge. Whether you enforce this depends on the project, but it's cheap insurance. See references/deploy-and-troubleshoot.md § Observability.
When you introduce a convention, say which bucket it's in ("this is universal" vs "matching this repo's house style") so the user can override the project-specific ones deliberately.
Don't guess at a component's option name.
references/authoring.md. Match thesurrounding file's commenting density and naming — these projects comment the why heavily, and a terse one-liner in a heavily-annotated file reads as a regression.
references/testing.md) andrun npx vitest (or the repo's test script). Run npx sst diff and/or tsc --noEmit to catch type and plan errors before deploying.
references/deploy-and-troubleshoot.md. Confirm thetarget account with aws sts get-caller-identity before any sst deploy.
must not linger in /tmp or chat history.
infra/ module, wired into run() in dependency order.
hand-set runtime unless intentionally diverging — e.g. a Python function).
link: (in-graph) and/or $interpolate-scopedIAM; outputs other tools consume are published to SSM under the stage prefix.
Context7 rather than relying on recall.
sst remove, a resource-type migration) wasflagged to the user with the account it targets, and migrations were planned as two PRs, not one.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.