diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..04f4c02 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e8e4fab --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + push: + branches: [dev, main] + pull_request: + branches: [dev, main] + +permissions: + contents: read + +jobs: + verify: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22 + cache: npm + - run: npm ci + - run: npm run typecheck + - run: npm run test + - run: npm run harness diff --git a/.github/workflows/release-promotion.yml b/.github/workflows/release-promotion.yml new file mode 100644 index 0000000..6368105 --- /dev/null +++ b/.github/workflows/release-promotion.yml @@ -0,0 +1,23 @@ +name: release-promotion + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + release-promotion: + runs-on: ubuntu-latest + if: github.event.repository.default_branch == 'dev' + env: + HEAD_REF: ${{ github.head_ref }} + HEAD_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }} + CURRENT_REPOSITORY: ${{ github.repository }} + steps: + - name: Require the repository-owned dev branch + shell: bash + run: | + test "$HEAD_REPOSITORY" = "$CURRENT_REPOSITORY" + test "$HEAD_REF" = "dev" diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..dcd3256 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,5 @@ +# Review ownership for security-sensitive infrastructure review code. +* @sjungwon03 +/actions/ @sjungwon03 +/packages/ @sjungwon03 +/.github/ @sjungwon03 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..91e78eb --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,29 @@ +# Contributor Covenant Code of Conduct + +## Our pledge + +We pledge to make participation in the PlanGuard community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our standards + +Examples of positive behavior include demonstrating empathy, respecting different viewpoints, giving and accepting constructive feedback, accepting responsibility, and focusing on what is best for the community. + +Unacceptable behavior includes harassment, sexualized language or imagery, trolling, insulting or derogatory comments, personal or political attacks, publishing private information without permission, and other conduct inappropriate in a professional setting. + +## Enforcement responsibilities + +Project maintainers are responsible for clarifying and enforcing this Code of Conduct. They may remove, reject, or edit comments, commits, code, issues, pull requests, and other contributions that are not aligned with it. + +## Scope + +This Code applies in all PlanGuard project spaces and when an individual officially represents the project in public spaces. + +## Enforcement + +Do not post sensitive Code of Conduct reports in public issues. If you need a confidential conversation, contact a Theorvane organization owner through their GitHub profile and state that the matter concerns conduct; do not use the security vulnerability form for non-security reports. Maintainers may take corrective action ranging from a warning to a temporary or permanent ban. + +## Attribution + +Adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5cd8b0b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,46 @@ +# Contributing to PlanGuard + +Thanks for contributing to PlanGuard. This project is released under the [MIT License](LICENSE). By submitting a contribution, you agree to license it under that license and to follow the [Code of Conduct](CODE_OF_CONDUCT.md). + +## Project boundary + +PlanGuard reviews Terraform change data. **Risk scores, policy pass/fail decisions, and cost numbers are computed by deterministic code, never by an LLM.** AI may summarize or explain deterministic output only. Read [AGENTS.md](AGENTS.md) before changing analysis, Actions, or agent code. + +Do not commit credentials, Terraform state, raw sensitive plans, private endpoints, or production data. + +## Development setup + +- Node.js 22 or later +- npm (the lockfile is authoritative) + +```bash +npm ci +npm run typecheck +npm run test +npm run harness +``` + +`npm run harness` verifies tool wiring without a model key. A live model invocation is optional and requires locally configured credentials; never place those credentials in a commit, issue, or pull request. + +## Contribution flow + +After the repository baseline is in place, PlanGuard uses `dev` as its integration branch and `main` for reviewed release promotion. + +1. Search existing issues, then open one focused issue with acceptance criteria. +2. Branch from updated `dev` as `/-`; for example, `fix/123-redaction-boundary`. +3. Add or update focused tests before changing behavior. +4. Use conventional commits such as `fix: preserve nested sensitive redaction`. +5. Open a pull request targeting `dev`, with `Closes #` in its body. +6. Run the relevant checks and record the commands/results in the PR. +7. Resolve review feedback. Maintainers merge only reviewed, green PRs. +8. Promote `dev` to release-only `main` through a separate reviewed PR. + +## Pull request expectations + +- Keep each PR focused and explain the user-facing or security impact. +- Update documentation and tests with behavior changes. +- Preserve the two-job security boundary in the BYO-AI workflow: Terraform preparation has no model key; the fresh explanation job runs no Terraform and reads only the sanitized artifact. +- Do not add `pull_request_target` to the public workflow or run unreviewed Terraform beside secrets or cloud credentials. +- Keep third-party Actions pinned to immutable commit SHAs in public examples. + +For suspected vulnerabilities, follow [SECURITY.md](SECURITY.md) instead of filing a public issue. diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..0c04340 --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,24 @@ +# Governance + +## Maintainers + +The Theorvane organization maintains PlanGuard. Repository administrators manage access, release tags, security settings, and branch rules. + +## Decision model + +- **Issues** establish scope, acceptance criteria, and non-goals. +- **Pull requests** are the unit of review and delivery. +- **`dev`** is the protected integration branch. +- **`main`** is release-only and accepts reviewed promotions from the repository-owned `dev` branch. + +## Merge requirements + +Maintainers require a focused linked issue, passing required checks, a review approval, and resolved review threads before merging. Deterministic-risk, authentication, artifact-boundary, workflow, or release changes receive security-focused review. + +## Release authority + +Only maintainers may move stable Action tags (including `v1`) and publish GitHub releases. Releases must be made from reviewed `dev` → `main` promotions. The immutable release commit is the recommended supply-chain pin; `@v1` is a maintainer-controlled convenience tag. + +## Changes to this document + +Changes to governance, branch protection, or release policy require a reviewed pull request and must preserve a working contribution path. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..93a2dd4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Theorvane + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index fb10191..62ccfbf 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ > Review Terraform changes safely in GitHub Actions, with an optional explanation from your own AI provider. [![Release](https://img.shields.io/github/v/release/Theorvane/planguard?display_name=tag&sort=semver)](https://github.com/Theorvane/planguard/releases/latest) +[![License](https://img.shields.io/github/license/Theorvane/planguard)](LICENSE) PlanGuard is a GitHub Actions tool for reviewing Terraform plans. It runs in your repository's GitHub runner; it does not require a hosted PlanGuard service, Render deployment, or GitHub App. AI explanations are optional, and the provider API key is supplied only from your GitHub Actions secrets. @@ -179,6 +180,7 @@ OpenAI-compatible endpoints currently require a public IPv4 DNS answer for an HT - [Release: v1.0.0](https://github.com/Theorvane/planguard/releases/tag/v1.0.0) - [Complete workflow example](examples/workflows/ai-terraform-review.yml) - [Marketplace publishing and release operations](docs/marketplace/README.md) +- [Contributing](CONTRIBUTING.md), [security policy](SECURITY.md), [support](SUPPORT.md), and [governance](GOVERNANCE.md) - [Product plan](docs/PRODUCT_PLAN.md) (Korean) - [Developer and agent guidance](AGENTS.md) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..3025ee4 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,26 @@ +# Security policy + +## Supported versions + +Security fixes are applied to the current `main` release line. When reporting a problem, identify the release tag or commit you tested. + +## Reporting a vulnerability + +**Do not open a public GitHub issue for a suspected vulnerability.** Do not include API keys, private keys, Terraform state, raw sensitive plan data, private endpoints, customer data, or exploit details in public issues, pull requests, workflow logs, or discussions. + +Use GitHub's [private vulnerability reporting](https://github.com/Theorvane/planguard/security/advisories/new) form for this repository. It is visible to repository maintainers and is the supported channel for sensitive disclosure. Include the affected release tag or commit, a minimal safe reproduction, impact, and remediation ideas if available. Do not attach live credentials or customer data. + +Maintainers will acknowledge a valid report, triage the impact, coordinate a fix and disclosure timing with the reporter, and credit the reporter only with their permission. + +## Scope + +This policy covers PlanGuard source code, GitHub Actions, published Action releases, CI workflows, and documented release or supply-chain paths. Infrastructure outside this repository and credentials committed by another project may be out of scope, but maintainers will triage reports in good faith once a private channel is available. + +## Security design boundary + +- Deterministic code owns policy, risk, cost, and pass/fail outcomes. +- The optional AI provider produces explanation only and cannot change a deterministic verdict. +- The public BYO-AI workflow separates Terraform preparation from the secret-bearing explanation job. +- Only a redacted plan artifact may cross that job boundary. + +Please preserve these boundaries in all contributions. diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..8af34df --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,19 @@ +# Support + +## Where to ask + +- **Bug reports:** Use the repository's bug-report issue template with a minimal reproducible example. +- **Feature proposals:** Use the feature-request template after checking existing issues and [docs/](docs/). +- **Contribution questions:** Read [CONTRIBUTING.md](CONTRIBUTING.md), [AGENTS.md](AGENTS.md), and relevant documentation first. If the answer remains unclear, open an issue with the context you reviewed. +- **Security reports:** Never post sensitive details publicly. Read [SECURITY.md](SECURITY.md) for the current reporting policy. + +## Before opening an issue + +1. Search existing issues and documentation. +2. Reduce the problem to the smallest safe reproduction. +3. Remove API keys, Terraform state, raw sensitive values, private URLs, and production data. +4. Include the PlanGuard release/commit, Node.js version, Terraform version when applicable, and sanitized error output. + +## Maintainer support + +Maintainers can clarify documented public behavior, supported workflows, contribution process, and roadmap. They cannot troubleshoot private cloud infrastructure, recover credentials, or access a caller's CI secrets.