npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@clef-sh/cdk

v0.5.1

Published

AWS CDK L2 constructs for delivering Clef-managed secrets to AWS resources

Readme

@clef-sh/cdk

AWS CDK L2 constructs for delivering Clef-managed secrets into AWS-native resources at deploy time. One construct call, one explicit IAM grant, no agent to run, no app-code changes.

npm install @clef-sh/cdk

Peer deps: aws-cdk-lib ^2.100, constructs ^10. For KMS-envelope identities (recommended), also install @aws-sdk/client-kms.

What's included

| Construct | Use case | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ClefArtifactBucket | Deliver the encrypted envelope to S3 for the Clef agent (or any VCS-compatible client) to fetch and decrypt at runtime. | | ClefSecret | Unwrap the envelope at deploy time and store the plaintext in AWS Secrets Manager. Consumers read via the native ASM SDK / ECS secret injection — no Clef agent required. | | ClefParameter | Unwrap the envelope at deploy time and store the plaintext in an SSM Parameter Store parameter. One construct = one parameter. Consumers read via ssm:GetParameter. |

Quick start

S3 delivery (any identity type)

import { ClefArtifactBucket } from "@clef-sh/cdk";

const artifact = new ClefArtifactBucket(this, "ApiSecrets", {
  identity: "api-gateway",
  environment: "production",
});

// Consumer wiring — explicit, reviewer-visible
artifact.grantRead(agentLambda); // s3:GetObject
artifact.envelopeKey?.grantDecrypt(agentLambda); // kms:Decrypt (KMS identities only)

Artifact signing (KMS asymmetric)

Pass the ARN of an asymmetric KMS key (key spec ECC_NIST_P256, algorithm ECDSA_SHA_256) as signingKeyArn to sign the envelope at cdk synth time. The construct provisions a deploy-time kms:GetPublicKey lookup and exposes the public key as a CFN token, so consumers can wire CLEF_AGENT_VERIFY_KEY without ever holding key bytes themselves.

The recommended pattern uses the static helper ClefArtifactBucket.signingKeyArnFromAlias, which resolves the alias's region/account at synth via kms.Key.fromLookup and rewrites the result back into alias-ARN form. KMS resolves the alias on every Sign / GetPublicKey call, so rotating the underlying key needs no stack changes.

import { ClefArtifactBucket } from "@clef-sh/cdk";

const artifact = new ClefArtifactBucket(this, "ApiSecrets", {
  identity: "api-gateway",
  environment: "production",
  signingKeyArn: ClefArtifactBucket.signingKeyArnFromAlias(this, "alias/clef-signing"),
});

artifact.grantRead(agentLambda);
artifact.envelopeKey?.grantDecrypt(agentLambda);
artifact.bindVerifyKey(agentLambda); // adds CLEF_AGENT_VERIFY_KEY env var

The helper requires AWS credentials with kms:DescribeKey at first synth; subsequent synths read from cdk.context.json. Commit cdk.context.json so CI synths are deterministic and don't need AWS credentials at synth time. If the alias is later re-targeted to a key in a different account or region, run cdk context --reset and re-synth. (Re-targeting within the same account/region is transparent to the cache — KMS resolves the alias at runtime.)

If you already have an ARN string in hand (from a platform-stack output, an SSM parameter you read in a config file, etc.), pass it directly:

signingKeyArn: "arn:aws:kms:us-east-1:111122223333:alias/clef-signing",

signingKeyArn must be a literal string at synth — CFN tokens are rejected. Signing happens in a subprocess outside the CFN graph, so a token resolved at deploy time is too late. Same-stack new kms.Key(...) and cross-stack token references will throw with a clear error.

Provision the signing key in a long-lived platform stack. The principal running cdk synth (developer laptop or CI role) needs kms:Sign on the key — the construct does not auto-grant.

Direct key ARNs (...:key/abcd-...) work too but couple the stack to a specific key generation; the alias form is preferred unless you have a reason to pin.

Only KMS asymmetric signing is supported via the CDK constructs. Ed25519 signing remains available through the CLI (clef pack --signing-key) but is intentionally not driven by CLEF_SIGNING_KEY in CDK synth — the construct prop is the only signal that signing is wanted, so a stray env var in CI cannot silently activate signing the user did not declare.

Signing applies only to ClefArtifactBucket. ClefSecret and ClefParameter unwrap the envelope at deploy time and write plaintext into AWS Secrets Manager / SSM, so the signed envelope never crosses a runtime trust boundary in those flows.

AWS Secrets Manager delivery (KMS-envelope identities)

import { ClefSecret } from "@clef-sh/cdk";

// Single-value secret — connection string, API token, webhook URL, etc.
const dbUrl = new ClefSecret(this, "DbUrl", {
  identity: "api-gateway",
  environment: "production",
  shape: "postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:5432/app",
});

// JSON-shaped secret — multiple fields, mapping Clef keys to app-expected names
const config = new ClefSecret(this, "Config", {
  identity: "api-gateway",
  environment: "production",
  shape: {
    dbHost: "${DATABASE_HOST}",
    apiKey: "${API_KEY}",
    region: "us-east-1", // literal
  },
});

dbUrl.grantRead(apiLambda);
config.grantRead(apiLambda);

Each new ClefSecret(…) provisions one ASM secret, same as native secretsmanager.Secret. The pack-helper is memoized per (manifest, identity, environment), so multiple instances for the same identity share a single pack invocation at synth.

SSM Parameter Store delivery (KMS-envelope identities)

import { ClefParameter } from "@clef-sh/cdk";

const dbUrl = new ClefParameter(this, "DbUrl", {
  identity: "api-gateway",
  environment: "production",
  shape: "postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:5432/app",
});

const stripe = new ClefParameter(this, "StripeKey", {
  identity: "api-gateway",
  environment: "production",
  shape: "${STRIPE_SECRET_KEY}",
});

dbUrl.grantRead(apiLambda);
stripe.grantRead(paymentsLambda);

ClefParameter is single-value only (SSM holds one value per parameter), so shape is required and must be a string template. Defaults to SecureString with the AWS-managed alias/aws/ssm at-rest key. Shares the unwrap Lambda and per-deploy KMS grant lifecycle with ClefSecret.

Existing Lambdas using SecretsManagerClient.GetSecretValue or ECS services using Secret.fromSecretsManager(secret, "FIELD") keep working unchanged — the construct shapes ASM to match what your app already reads.

How ClefSecret stays secure

Conventional "unwrap Lambda" designs leave a long-lived Lambda with persistent kms:Decrypt in your account — an attractive target for anyone who pivots into the runtime. ClefSecret uses per-deploy KMS grants instead:

  • The unwrap Lambda's role has no baseline kms:Decrypt.
  • On each deploy, a sibling CloudFormation Custom Resource calls kms:CreateGrant scoped to GranteePrincipal = unwrap-role and Operations = [Decrypt]. Authority lasts for one invocation.
  • When the envelope revision changes (every cdk deploy), CloudFormation replaces the grant resource — RevokeGrant runs on the previous grant before the new one takes over.

Between deploys the Lambda is cold and, on its own, cannot decrypt anything. Ciphertext in stack resource properties is safe at rest (same threat model Clef assumes everywhere else).

Synth-time validation

Shape templates are validated before CloudFormation sees them. Typos surface at cdk synth with the field name (or <value> for string shape), the bad reference, a did-you-mean suggestion, and the full list of valid Clef keys for that identity/environment. No broken deploys, no rollback dances.

Requirements at synth time

  • sops binary on PATH, or bundled via the matching @clef-sh/sops-* platform package (installed automatically with @clef-sh/cli).
  • Age credentialsCLEF_AGE_KEY or CLEF_AGE_KEY_FILE env var pointing at the user's age private key. Used to decrypt source SOPS files during the pack step.
  • AWS credentials — required for KMS-envelope identities; the synth calls kms:Encrypt to wrap a fresh DEK into the envelope. Standard AWS SDK credential resolution (AWS_PROFILE, env vars, instance role, etc.).

Full docs

License

MIT