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

@c6fc/spellcraft-aws-s3

v2.0.0

Published

Secure-by-default S3 bucket factory. Encryption, ownership and public-access blocks are on unless you opt out.

Readme

@c6fc/spellcraft-aws-s3

Secure-by-default S3 buckets for SpellCraft, in one line of Jsonnet.

NPM version License

Pure Jsonnet — no native functions of its own. It composes the fourteen-odd Terraform resources a properly configured bucket actually needs, and asks you only for what differs from a sensible default.

npm install --save @c6fc/spellcraft-aws-s3 @c6fc/spellcraft-aws-terraform

A complete spell

Buckets are bound to a regional provider alias, so a spell declares its providers once and every resource-producing plugin uses them. providerAliases() builds the whole set from your live account:

local aws = import "@c6fc/spellcraft-aws-terraform/module.libsonnet";
local s3 = import "@c6fc/spellcraft-aws-s3/module.libsonnet";

{
	"providers.tf.json": {
		provider: aws.providerAliases("us-east-1"),
	},

	// Defaults only: KMS-encrypted, public access blocked, TLS 1.2 enforced.
	"buckets.tf.json": s3.bucket("artifacts", "us-west-2")

		// A public static site.
		+ s3.bucket("site", "us-west-2", { type: "static-site" })

		// Versioning on, and a couple of defaults relaxed.
		+ s3.bucket("scratch", "eu-west-1", {
			versioning: "Enabled",
			server_side_encryption: false,
		}),
}

providerAliases("us-east-1") emits an aliased aws provider for every region your credentials can see, plus an unaliased default for the region you name. The second argument to bucket() picks which alias its resources bind to.

The same shape applies on GCP with @c6fc/spellcraft-gcp-terraform.

Bucket names

The first argument is the Terraform resource key, and the bucket is created with bucket_prefix rather than a literal name — so s3.bucket("artifacts", ...) deploys a bucket called artifacts-<suffix>, with the suffix generated by AWS.

S3 bucket names are globally unique across every AWS account, and this keeps that from being something you negotiate by hand. Reference the real name from Terraform the usual way:

{ value: "${aws_s3_bucket.artifacts.id}" }

Defaults

With no options at all, a bucket gets:

  • server-side encryption with its own customer-managed KMS key, rotation enabled
  • all four public access blocks on
  • a bucket policy denying any request below TLS 1.2
  • BucketOwnerEnforced object ownership
  • bucket owner as request payer
  • versioning disabled

Resources beyond the bucket are only emitted when the corresponding option is set, so a default bucket produces eight resources rather than every one the module knows how to build.

Types

type selects a preset. Options you pass alongside it win over the preset.

static-site

Public-readable website hosting: public_access_block: false, server_side_encryption: false, website: true, and a policy statement allowing s3:GetObject to any principal.

log-storage

A destination for S3 access logs: acl: "log-delivery-write" with object_ownership: "ObjectWriter". Both are needed — a canned ACL is ignored entirely under BucketOwnerEnforced, so the ownership change is what makes the ACL take effect.

API Reference

bucket(name, region, options = {})

Builds a secure-by-default S3 bucket and its supporting resources.

Returns a { resource: { ... } } object, so it can be a whole .tf.json file on its own or merged with + alongside other resources.

With no options you get a KMS-encrypted bucket with its own customer-managed key and rotation enabled, all four public access blocks on, a policy that denies any request below TLS 1.2, BucketOwnerEnforced ownership, and versioning disabled. Pass a type for a common preset, or any option below to override one default. Anything not recognised as an option is passed straight through as an attribute of aws_s3_bucket.

name is the Terraform resource key, not the bucket name: the bucket is created with bucket_prefix, so its deployed name is <name>-<suffix> with a suffix AWS generates. That keeps the globally-unique S3 namespace from being something you have to negotiate by hand.

Every resource is bound to provider: "aws.<region>", so the spell needs matching provider aliases — see providerAliases() in @c6fc/spellcraft-aws-terraform.

  • param {string} name - the Terraform resource key, and the bucket's name prefix
  • param {string} region - the region alias to bind every resource to
  • param {object} [options={}] - overrides; see the option reference in the README
  • returns {object} a Terraform resource block

Examples:

local s3 = import "@c6fc/spellcraft-aws-s3/module.libsonnet";

{ "buckets.tf.json": s3.bucket("artifacts", "us-west-2") }
local s3 = import "@c6fc/spellcraft-aws-s3/module.libsonnet";

// A public static site, and a log bucket that can receive delivery writes.
{
  "site.tf.json": s3.bucket("site", "us-west-2", { type: "static-site" })
    + s3.bucket("logs", "us-west-2", { type: "log-storage" }),
}

Options

Anything not listed here is passed straight through as an attribute of aws_s3_bucket.

acceleration_status (default: false)

Transfer acceleration. Allowed: Enabled, Suspended.

acl (default: false)

A canned ACL. Only takes effect when object_ownership is not BucketOwnerEnforced.

allow_insecure_access (default: false)

Set true to omit the policy statement that denies requests below TLS 1.2 — in other words, to permit plain HTTP.

cors_rule (default: [])

An array of CORS rules. See aws_s3_bucket_cors_configuration.

lifecycle_rule (default: [])

An array of lifecycle rules. See aws_s3_bucket_lifecycle_configuration.

logging (default: "")

The name (not ARN) of a bucket to deliver access logs to. Objects are prefixed <account-id>/<name>-.

object_lock_configuration (default: [])

An array of object lock rules. See aws_s3_bucket_object_lock_configuration.

object_ownership (default: "BucketOwnerEnforced")

Allowed: BucketOwnerEnforced, BucketOwnerPreferred, ObjectWriter.

policy_statements (default: [])

An array of IAM policy statements for the bucket policy, written as IAM accepts them — not Terraform's policy objects. Merged with the TLS deny statement unless allow_insecure_access is set.

public_access_block (default: true)

Sets all four public access block settings together.

replication_configuration (default: {})

A complete replication configuration — an object carrying role (the ARN of the IAM role S3 assumes) and rule. Passed through whole, because the resource needs both. See aws_s3_bucket_replication_configuration. Replication requires versioning enabled on both the source and destination buckets.

s3.bucket("replicated", "us-west-2", {
	versioning: "Enabled",
	replication_configuration: {
		role: "${aws_iam_role.replication.arn}",
		rule: [{
			id: "everything",
			status: "Enabled",
			destination: { bucket: "${aws_s3_bucket.backup.arn}" },
		}],
	},
})

request_payer (default: "BucketOwner")

Allowed: BucketOwner, Requester.

server_side_encryption (default: true)

When true, provisions a dedicated KMS customer-managed key and encrypts with it. Set false for no SSE configuration.

versioning (default: "Disabled")

Allowed: Enabled, Suspended, Disabled.

website (default: {})

true for a default configuration of index.html and error.html, or an aws_s3_bucket_website_configuration object for anything else.

Development

npm test        # renders test.jsonnet through a real SpellFrame
npm run doc     # regenerates the API section above from module.libsonnet

npm test needs AWS credentials — the module resolves your account ID at evaluation time for the KMS key policy — but it is read-only and creates nothing.

License

MIT © Brad Woodward