{"_id":"@c6fc/spellcraft-aws-s3","_rev":"2-7ddef564dbc2f8353ebe096154ef7cd9","name":"@c6fc/spellcraft-aws-s3","dist-tags":{"latest":"2.0.0"},"versions":{"1.0.0":{"name":"@c6fc/spellcraft-aws-s3","version":"1.0.0","author":{"name":"Brad Woodward","email":"brad@bradwoodward.io"},"license":"MIT","_id":"@c6fc/spellcraft-aws-s3@1.0.0","maintainers":[{"name":"c6fc","email":"brad@bradwoodward.io"}],"homepage":"https://github.com/you/@c6fc/spellcraft-aws-s3#readme","bugs":{"url":"https://github.com/you/@c6fc/spellcraft-aws-s3/issues"},"dist":{"shasum":"8b0d86e150868d02964435561ffcf8f30bc52bd0","tarball":"https://registry.npmjs.org/@c6fc/spellcraft-aws-s3/-/spellcraft-aws-s3-1.0.0.tgz","fileCount":9,"integrity":"sha512-zRducYRxbmzBOU1iZq8CIT1LcjIFUDmpCvbn0NjU0buwa0T5hoBIGDlW1oDwxNtfutGthI/f3+Gstw5jukC1og==","signatures":[{"sig":"MEQCIC90me+xlOLkqUmZ77aBTlSw+0mQykSITZCFGz+SxZWfAiA60LhQUhh6EZ2Y6A+sL9vzmhp4M6FnEymh073lxvYnrQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18375},"main":"module.js","config":{"spellcraft_module_default_name":"s3"},"gitHead":"7ee4be5126071fc545799a685ac5bce013cbabf5","scripts":{"cli":"utils/cli-test.js","doc":"jsdoc -c utils/jsdoc.json --verbose","test":"node utils/test.js"},"_npmUser":{"name":"c6fc","actor":{"name":"c6fc","type":"user","email":"brad@bradwoodward.io"},"email":"brad@bradwoodward.io"},"repository":{"url":"git+https://github.com/you/@c6fc/spellcraft-aws-s3.git","type":"git"},"_npmVersion":"10.8.2","description":"A plugin to add functionality via @c6fc/spellcraft","directories":{},"_nodeVersion":"20.19.0","dependencies":{"@c6fc/spellcraft":"^0.0.5","@c6fc/spellcraft-aws-auth":"^1.0.7"},"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^4.0.4","clean-jsdoc-theme":"^4.3.0"},"_npmOperationalInternal":{"tmp":"tmp/spellcraft-aws-s3_1.0.0_1751155707072_0.8583953849742549","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@c6fc/spellcraft-aws-s3","version":"2.0.0","main":"module.js","scripts":{"cli":"node utils/cli-test.js","doc":"spellcraft doc","test":"node utils/test.js"},"repository":{"type":"git","url":"git+https://github.com/c6fc/spellcraft-aws-s3.git"},"spellcraft":true,"author":{"name":"Brad Woodward","email":"brad@bradwoodward.io"},"license":"MIT","bugs":{"url":"https://github.com/c6fc/spellcraft-aws-s3/issues"},"homepage":"https://github.com/c6fc/spellcraft-aws-s3#readme","description":"Secure-by-default S3 bucket factory. Encryption, ownership and public-access blocks are on unless you opt out.","peerDependencies":{"@c6fc/spellcraft":"^1.0.0","@c6fc/spellcraft-aws-auth":"^2.0.0"},"devDependencies":{"@c6fc/spellcraft":"^1.0.0","@c6fc/spellcraft-aws-auth":"^2.0.0","yargs":"^18.0.0"},"engines":{"node":">=18"},"_id":"@c6fc/spellcraft-aws-s3@2.0.0","gitHead":"6e0b73822643bf312e10f6f0b7def02a9d102af2","_nodeVersion":"20.19.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-pfE0VJSDyWGP5Z1JPCsjZYY9G5jTD1Tynzeiv6g7s6TvOhcROGpJuNtxQojZxbT8yXu8y7fkFaUajTnfiwK/Jw==","shasum":"fad0c03a1ac84c7c4a84ade4f5a1eb1bd8b20739","tarball":"https://registry.npmjs.org/@c6fc/spellcraft-aws-s3/-/spellcraft-aws-s3-2.0.0.tgz","fileCount":6,"unpackedSize":21076,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQClXZN5BodIXzhMjD4o3OOqgFGNDc153erNh7z2hxWhiAIhAOfcIwbhhKrl+0h1QBBnydojVHhedUYRFXMOi8tC+EiZ"}]},"_npmUser":{"name":"c6fc","email":"brad@bradwoodward.io"},"directories":{},"maintainers":[{"name":"c6fc","email":"brad@bradwoodward.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/spellcraft-aws-s3_2.0.0_1788728985061_0.0901097737295049"},"_hasShrinkwrap":false}},"time":{"created":"2025-06-29T00:08:26.988Z","modified":"2026-09-06T21:09:45.316Z","1.0.0":"2025-06-29T00:08:27.245Z","2.0.0":"2026-09-06T21:09:45.191Z"},"bugs":{"url":"https://github.com/c6fc/spellcraft-aws-s3/issues"},"author":{"name":"Brad Woodward","email":"brad@bradwoodward.io"},"license":"MIT","homepage":"https://github.com/c6fc/spellcraft-aws-s3#readme","repository":{"type":"git","url":"git+https://github.com/c6fc/spellcraft-aws-s3.git"},"description":"Secure-by-default S3 bucket factory. Encryption, ownership and public-access blocks are on unless you opt out.","maintainers":[{"name":"c6fc","email":"brad@bradwoodward.io"}],"readme":"# @c6fc/spellcraft-aws-s3\n\nSecure-by-default S3 buckets for [SpellCraft](https://github.com/c6fc/spellcraft),\nin one line of Jsonnet.\n\n[![NPM version](https://img.shields.io/npm/v/@c6fc/spellcraft-aws-s3.svg?style=flat)](https://www.npmjs.com/package/@c6fc/spellcraft-aws-s3)\n[![License](https://img.shields.io/npm/l/@c6fc/spellcraft-aws-s3.svg?style=flat)](https://opensource.org/licenses/MIT)\n\nPure Jsonnet — no native functions of its own. It composes the fourteen-odd\nTerraform resources a properly configured bucket actually needs, and asks you\nonly for what differs from a sensible default.\n\n```bash\nnpm install --save @c6fc/spellcraft-aws-s3 @c6fc/spellcraft-aws-terraform\n```\n\n## A complete spell\n\nBuckets are bound to a regional provider alias, so a spell declares its\nproviders once and every resource-producing plugin uses them. `providerAliases()`\nbuilds the whole set from your live account:\n\n```jsonnet\nlocal aws = import \"@c6fc/spellcraft-aws-terraform/module.libsonnet\";\nlocal s3 = import \"@c6fc/spellcraft-aws-s3/module.libsonnet\";\n\n{\n\t\"providers.tf.json\": {\n\t\tprovider: aws.providerAliases(\"us-east-1\"),\n\t},\n\n\t// Defaults only: KMS-encrypted, public access blocked, TLS 1.2 enforced.\n\t\"buckets.tf.json\": s3.bucket(\"artifacts\", \"us-west-2\")\n\n\t\t// A public static site.\n\t\t+ s3.bucket(\"site\", \"us-west-2\", { type: \"static-site\" })\n\n\t\t// Versioning on, and a couple of defaults relaxed.\n\t\t+ s3.bucket(\"scratch\", \"eu-west-1\", {\n\t\t\tversioning: \"Enabled\",\n\t\t\tserver_side_encryption: false,\n\t\t}),\n}\n```\n\n`providerAliases(\"us-east-1\")` emits an aliased `aws` provider for every region\nyour credentials can see, plus an unaliased default for the region you name. The\nsecond argument to `bucket()` picks which alias its resources bind to.\n\nThe same shape applies on GCP with `@c6fc/spellcraft-gcp-terraform`.\n\n## Bucket names\n\nThe first argument is the **Terraform resource key**, and the bucket is created\nwith `bucket_prefix` rather than a literal name — so `s3.bucket(\"artifacts\", ...)`\ndeploys a bucket called `artifacts-<suffix>`, with the suffix generated by AWS.\n\nS3 bucket names are globally unique across every AWS account, and this keeps that\nfrom being something you negotiate by hand. Reference the real name from\nTerraform the usual way:\n\n```jsonnet\n{ value: \"${aws_s3_bucket.artifacts.id}\" }\n```\n\n## Defaults\n\nWith no options at all, a bucket gets:\n\n- server-side encryption with its **own** customer-managed KMS key, rotation enabled\n- all four public access blocks on\n- a bucket policy denying any request below TLS 1.2\n- `BucketOwnerEnforced` object ownership\n- bucket owner as request payer\n- versioning disabled\n\nResources beyond the bucket are only emitted when the corresponding option is\nset, so a default bucket produces eight resources rather than every one the\nmodule knows how to build.\n\n## Types\n\n`type` selects a preset. Options you pass alongside it win over the preset.\n\n### `static-site`\n\nPublic-readable website hosting: `public_access_block: false`,\n`server_side_encryption: false`, `website: true`, and a policy statement allowing\n`s3:GetObject` to any principal.\n\n### `log-storage`\n\nA destination for S3 access logs: `acl: \"log-delivery-write\"` with\n`object_ownership: \"ObjectWriter\"`. Both are needed — a canned ACL is ignored\nentirely under `BucketOwnerEnforced`, so the ownership change is what makes the\nACL take effect.\n\n<!-- SPELLCRAFT_DOCS_API_START -->\n## API Reference\n\n### `bucket(name, region, options = {})`\n\nBuilds a secure-by-default S3 bucket and its supporting resources.\n\nReturns a `{ resource: { ... } }` object, so it can be a whole `.tf.json`\nfile on its own or merged with `+` alongside other resources.\n\nWith no options you get a KMS-encrypted bucket with its own customer-managed\nkey and rotation enabled, all four public access blocks on, a policy that\ndenies any request below TLS 1.2, `BucketOwnerEnforced` ownership, and\nversioning disabled. Pass a `type` for a common preset, or any option below\nto override one default. Anything not recognised as an option is passed\nstraight through as an attribute of `aws_s3_bucket`.\n\n`name` is the Terraform resource key, not the bucket name: the bucket is\ncreated with `bucket_prefix`, so its deployed name is `<name>-<suffix>` with\na suffix AWS generates. That keeps the globally-unique S3 namespace from\nbeing something you have to negotiate by hand.\n\nEvery resource is bound to `provider: \"aws.<region>\"`, so the spell needs\nmatching provider aliases — see `providerAliases()` in\n`@c6fc/spellcraft-aws-terraform`.\n\n- param {string} name - the Terraform resource key, and the bucket's name prefix\n- param {string} region - the region alias to bind every resource to\n- param {object} [options={}] - overrides; see the option reference in the README\n- returns {object} a Terraform `resource` block\n\n**Examples:**\n\n```jsonnet\nlocal s3 = import \"@c6fc/spellcraft-aws-s3/module.libsonnet\";\n\n{ \"buckets.tf.json\": s3.bucket(\"artifacts\", \"us-west-2\") }\n```\n\n```jsonnet\nlocal s3 = import \"@c6fc/spellcraft-aws-s3/module.libsonnet\";\n\n// A public static site, and a log bucket that can receive delivery writes.\n{\n  \"site.tf.json\": s3.bucket(\"site\", \"us-west-2\", { type: \"static-site\" })\n    + s3.bucket(\"logs\", \"us-west-2\", { type: \"log-storage\" }),\n}\n```\n\n---\n\n<!-- SPELLCRAFT_DOCS_API_END -->\n\n## Options\n\nAnything not listed here is passed straight through as an attribute of\n`aws_s3_bucket`.\n\n### `acceleration_status` (default: `false`)\n\nTransfer acceleration. Allowed: `Enabled`, `Suspended`.\n\n### `acl` (default: `false`)\n\nA canned ACL. Only takes effect when `object_ownership` is not\n`BucketOwnerEnforced`.\n\n### `allow_insecure_access` (default: `false`)\n\nSet `true` to omit the policy statement that denies requests below TLS 1.2 — in\nother words, to permit plain HTTP.\n\n### `cors_rule` (default: `[]`)\n\nAn array of CORS rules. See\n[aws_s3_bucket_cors_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_cors_configuration).\n\n### `lifecycle_rule` (default: `[]`)\n\nAn array of lifecycle rules. See\n[aws_s3_bucket_lifecycle_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration).\n\n### `logging` (default: `\"\"`)\n\nThe **name** (not ARN) of a bucket to deliver access logs to. Objects are\nprefixed `<account-id>/<name>-`.\n\n### `object_lock_configuration` (default: `[]`)\n\nAn array of object lock rules. See\n[aws_s3_bucket_object_lock_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_object_lock_configuration).\n\n### `object_ownership` (default: `\"BucketOwnerEnforced\"`)\n\nAllowed: `BucketOwnerEnforced`, `BucketOwnerPreferred`, `ObjectWriter`.\n\n### `policy_statements` (default: `[]`)\n\nAn array of IAM policy statements for the bucket policy, written as IAM accepts\nthem — not Terraform's policy objects. Merged with the TLS deny statement unless\n`allow_insecure_access` is set.\n\n### `public_access_block` (default: `true`)\n\nSets all four public access block settings together.\n\n### `replication_configuration` (default: `{}`)\n\nA complete replication configuration — an object carrying `role` (the ARN of the\nIAM role S3 assumes) and `rule`. Passed through whole, because the resource needs\nboth. See\n[aws_s3_bucket_replication_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_replication_configuration).\nReplication requires versioning enabled on both the source and destination\nbuckets.\n\n```jsonnet\ns3.bucket(\"replicated\", \"us-west-2\", {\n\tversioning: \"Enabled\",\n\treplication_configuration: {\n\t\trole: \"${aws_iam_role.replication.arn}\",\n\t\trule: [{\n\t\t\tid: \"everything\",\n\t\t\tstatus: \"Enabled\",\n\t\t\tdestination: { bucket: \"${aws_s3_bucket.backup.arn}\" },\n\t\t}],\n\t},\n})\n```\n\n### `request_payer` (default: `\"BucketOwner\"`)\n\nAllowed: `BucketOwner`, `Requester`.\n\n### `server_side_encryption` (default: `true`)\n\nWhen true, provisions a dedicated KMS customer-managed key and encrypts with it.\nSet `false` for no SSE configuration.\n\n### `versioning` (default: `\"Disabled\"`)\n\nAllowed: `Enabled`, `Suspended`, `Disabled`.\n\n### `website` (default: `{}`)\n\n`true` for a default configuration of `index.html` and `error.html`, or an\n[aws_s3_bucket_website_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_website_configuration)\nobject for anything else.\n\n## Development\n\n```bash\nnpm test        # renders test.jsonnet through a real SpellFrame\nnpm run doc     # regenerates the API section above from module.libsonnet\n```\n\n`npm test` needs AWS credentials — the module resolves your account ID at\nevaluation time for the KMS key policy — but it is read-only and creates nothing.\n\n## License\n\nMIT © [Brad Woodward](https://github.com/c6fc)\n","readmeFilename":"README.md"}