diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..5029f10 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,46 @@ +name: Bug report +description: A documented deny isn't blocking what it should, or an allow is breaking something it shouldn't +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + **Security issues:** do NOT open a public bug. See [SECURITY.md](../../SECURITY.md) for private disclosure. + - type: dropdown + id: deployment-path + attributes: + label: Deployment path + options: + - CLI Quick Start (substitution helper + aws iam commands) + - Terraform module + - Other + validations: + required: true + - type: textarea + id: what-happened + attributes: + label: What happened + description: Describe the unexpected behavior. Include the exact AWS or Terraform error message if applicable. + placeholder: | + Running `terraform apply` with `iam_path = "/loki/"` produces: + Error: Error attaching policy ... AccessDenied: User is not authorized to perform iam:CreateRole on resource: ... + validations: + required: true + - type: textarea + id: expected + attributes: + label: What you expected + validations: + required: true + - type: textarea + id: caller-identity + attributes: + label: Caller identity + description: Output of `aws sts get-caller-identity` (redact account ID if you prefer) + validations: + required: false + - type: textarea + id: extra + attributes: + label: Anything else + description: Versions, config snippets, related issues diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..305d0ac --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,34 @@ +name: Feature request +description: Propose a new deny, a new threat-model scenario, or a usability improvement +labels: ["enhancement"] +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What gap or threat does this address? + placeholder: "PowerUserAccess permits XYZ which can be used to..." + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposed change + description: Specific Sids/actions/conditions you'd add or change. Include both JSON and Terraform sides. + validations: + required: true + - type: textarea + id: tradeoffs + attributes: + label: Trade-offs + description: What does this break or constrain? Day-2 ops impact? + validations: + required: false + - type: checkboxes + id: scope-check + attributes: + label: Threat-model fit + description: This repo is opinionated about a specific deployment shape (autonomous agent on private subnet, message-driven control). Does this proposal fit that? + options: + - label: This proposal fits the repo's documented threat model + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..21be5f4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,25 @@ +# Pull Request + +## What this PR does + + + +## Why + + + +## Type of change + +- [ ] New deny action(s) — added to BOTH `policies/deny-guardrails.json` AND `terraform/main.tf` +- [ ] Bug fix — existing deny wasn't blocking what it should +- [ ] Documentation +- [ ] CI / tooling +- [ ] Other (describe) + +## Checklist + +- [ ] If touching policies: JSON and Terraform sides updated together (CI parity check would fail otherwise) +- [ ] `terraform fmt -recursive` is clean +- [ ] No new placeholders introduced without README + substitution-helper updates +- [ ] No real account IDs / bucket names / KMS ARNs in fixtures +- [ ] Documented breaking changes in commit body if any (e.g., variable rename, IAM resource recreate) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..12b3c62 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,39 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone. + +## Our Standards + +Examples of behavior that contributes to a positive environment: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes +- Focusing on what is best for the overall community + +Examples of unacceptable behavior: + +- The use of sexualized language or imagery, and sexual attention or advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Maintainers are responsible for clarifying and enforcing our standards and will take appropriate and fair corrective action in response to any behavior they deem inappropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the maintainers at **conduct@inceptionstack.dev**. All complaints will be reviewed and investigated promptly and fairly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3ebb87a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,56 @@ +# Contributing to loki-permissions + +Thanks for your interest in improving this project. + +## What this repo is + +A scoped IAM policy template for AI DevOps agents running on AWS EC2. It is opinionated about a specific threat model (autonomous agents on private subnets, no SSH, message-driven control). Contributions that fit this threat model are welcome; contributions that broaden the scope to a generic IAM library are likely to be declined. + +## Reporting bugs + +Open a [GitHub issue](https://github.com/inceptionstack/loki-permissions/issues) using the bug template. Please include: + +- Which deployment path you used (CLI Quick Start / Terraform module) +- The exact `aws iam` or `terraform apply` error message +- Output of `aws sts get-caller-identity` (redact account ID if you prefer) +- Whether the failure is at `terraform plan`, `terraform apply`, or runtime + +## Suggesting changes + +For anything beyond a typo fix: + +1. Open an issue first describing the problem and proposed change +2. Wait for maintainer response before opening a PR — saves rework if the direction is wrong +3. Reference the issue in your PR + +## Pull requests + +- One concern per PR. Don't bundle a bugfix with refactoring. +- Run the linter locally before pushing: + ```bash + cd terraform + terraform fmt -recursive + terraform init -backend=false -input=false && terraform validate + # The full parity check (JSON ↔ Terraform) requires rendered statement + # files. See .github/workflows/lint.yml for the canonical render flow, + # then: python3 ../scripts/check_parity.py + ``` +- CI must pass. The lint workflow validates JSON, Terraform, and per-Sid action parity between JSON and Terraform forms. +- Update `policies/*.json` AND `terraform/main.tf` together. CI will fail on drift between the two encodings. + +## Adding new deny actions + +When extending the audit-tampering deny set: + +1. Add the action to BOTH `policies/deny-guardrails.json` and the corresponding `local` in `terraform/main.tf` +2. Group by service (cloudtrail / config / guardduty / securityhub / s3 / kms) +3. If the action requires a new placeholder or variable, document it in the README placeholder table +4. CI's parity check will fail if you forget either side + +## Security issues + +Do **not** open a public issue. See [SECURITY.md](SECURITY.md) for the private disclosure process. + +## License + +By contributing, you agree your contributions are licensed under the Apache License 2.0 (matching this project's LICENSE). diff --git a/README.md b/README.md index 1175851..b50c35a 100644 --- a/README.md +++ b/README.md @@ -273,6 +273,20 @@ Before deploying, update these values in the policy files: > > **Terraform users:** if you deploy via the `terraform/` module, set `trail_bucket_name` and `trail_kms_key_arn` (full ARN) variables — the module variable validation rejects partial ARNs at plan-time. Leave them `null` to skip the trail-storage and trail-KMS statements entirely. +## Contributing + +Contributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). The repo is +opinionated about a specific threat model (autonomous agent on private subnet, +message-driven control); changes that fit that model land easiest. + +## Security + +Found a way to bypass one of the documented denies, widen scope past the agent +path, or blind audit infrastructure? Do **not** open a public issue. See +[SECURITY.md](SECURITY.md) for private disclosure (security@inceptionstack.dev). + +Community guidelines: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) (Contributor Covenant 2.1). + ## License Apache License 2.0 — see [LICENSE](LICENSE). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..2d8436b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,45 @@ +# Security Policy + +## Reporting a Vulnerability + +This repo defines IAM policies that protect production AWS environments from agent-driven privilege escalation and audit-trail tampering. Security issues here can have high blast radius. + +**Do NOT open a public GitHub issue for security findings.** + +### Private disclosure + +Email security findings to: **security@inceptionstack.dev** + +Include: + +- A description of the issue and the threat it enables (privilege escalation, audit blinding, scope widening, etc.) +- The specific Sid / statement / variable / Terraform resource involved +- A proof-of-concept policy snippet or `aws iam simulate-principal-policy` invocation that demonstrates the issue +- Your suggested fix, if any + +You will receive an acknowledgement within 5 business days. + +### What counts as a vulnerability + +- A bypass of one of the documented denies (e.g., an action that should be blocked by `DenySelfEscalation` but isn't) +- A scope-widening pattern that defeats the agent-path restriction +- A footgun in the substitution helper or Terraform module that produces a syntactically valid but semantically wrong policy +- A regression in CI that lets JSON↔Terraform drift land on `main` + +### What doesn't + +- Suggestions to add deny actions that don't bypass an existing category — open a normal issue for those +- Concerns about deployments outside this repo's documented threat model (single-tenant agent on private subnet) +- IAM permissions intentionally allowed by `LokiIAMScoped` in agent-path scope + +## Supported versions + +This is a template repo; we maintain `main` only. If you fork, you are responsible for tracking upstream fixes. + +## Threat model recap + +See the [README](README.md#threat-model) for the full threat model. In short: + +- The agent is **trusted** to do legitimate DevOps work +- The agent is **not trusted** to escalate, persist as a new identity, or blind audit infrastructure +- Recovery from a compromised agent relies on CloudTrail integrity — the audit-tampering denies are the lynchpin