Skip to content

chore: add gitignore, buddy security profile and shared secret scanner - #682

Open
allanice001 wants to merge 3 commits into
mainfrom
chore/gitignore-and-buddy-profile
Open

chore: add gitignore, buddy security profile and shared secret scanner#682
allanice001 wants to merge 3 commits into
mainfrom
chore/gitignore-and-buddy-profile

Conversation

@allanice001

Copy link
Copy Markdown
Contributor

What

Three things, in dependency order.

1. A .gitignore, which this repo did not have at all.

This module mints IAM secret access keys and takes a GitHub App private key, an OAuth client secret and the autoglue org secret as inputs. Without a .gitignore, a stray *.tfstate, *.tfplan or *.tfvars commits live credentials. Now covered, along with Terraform working directories, crash logs and CLI config.

Verified no currently-tracked file becomes ignored — .terraform-docs.yml was the near-miss, and **/.terraform/* does not match it.

2. A committed dragon-dev-buddy profile at .dragon-buddy/config.json.

Records exposure (public — the module publishes Route53 zones and a *.apps wildcard pointing at cluster ingress), data sensitivity (credentials), the four real trust boundaries, and known risk areas. Security tooling reads this instead of re-deriving it each run. Tracked so the team shares one profile; reports/ is ignored because audit output quotes real findings.

3. A secret scanner guarding that decision.

A committed profile is readable by everyone with repo access, so a credential landing in it is a leak. .dragon-buddy/scan-config.py detects AWS access key ids, GitHub tokens and PATs, PEM private keys, Slack tokens, JWTs, Vault tokens, and opaque high-entropy values under secret-named keys. .dragon-buddy/scan-config.sh wraps it for both staged (hook) and file modes.

It is enforced twice, because either alone has a hole:

  • .githooks/pre-commit, tracked, enabled per clone with git config core.hooksPath .githooks. Fast local feedback, but core.hooksPath is local config and cannot be committed, so it can go unenabled.
  • .github/workflows/scan-buddy-profile.yml, running the same scanner on every PR. Covers everyone regardless.

Testing

Scanner unit-tested against six inputs: clean config passes; AWS key, GitHub token, PEM-in-prose, opaque-value-under-api_key, and empty-document all reject. Then end-to-end through the real hook via core.hooksPath — a commit carrying a seeded ghp_ token was refused and no commit object was created. CI step dry-run under bash; workflow YAML parses.

Worth noting the first version of the scanner was broken in a way that passed everything: a heredoc occupied python's stdin, so it read an empty document and exited clean. That is why the empty-document case is now an explicit failure rather than a silent success.

Notes for review

  • README.md is generated wholesale by terraform-docs from docs/.header.md, so the setup docs live in .dragon-buddy/README.md instead.
  • No Terraform changes. No resources added, changed or destroyed.
  • After merge, everyone should run git config core.hooksPath .githooks once.

The repo had no .gitignore at all. Given this module mints IAM secret
access keys and takes a GitHub App private key, an OAuth client secret
and the autoglue org secret as inputs, an accidentally committed
*.tfstate, *.tfplan or *.tfvars would leak live credentials. Ignore
those, plus Terraform working dirs, crash logs and CLI config.

Also add the dragon-dev-buddy profile that security tooling reads:
exposure (public, via the Route53 zones and the *.apps wildcard),
data sensitivity (credentials), trust boundaries and known risk areas.
config.json is tracked so the team shares one profile; reports/ is
ignored because audit output quotes real findings.

scan-config.sh + scan-config.py guard that decision: a pre-commit hook
blocks the commit if a credential-shaped value ever lands in the
profile. Install locally with:

  ln -sf ../../.dragon-buddy/scan-config.sh .git/hooks/pre-commit
.git/hooks/ is not shared by git, so the pre-commit guard added in the
previous commit only protected whoever installed it by hand. Move the
hook into a tracked .githooks/ directory, enabled per clone with:

  git config core.hooksPath .githooks

core.hooksPath is local config and cannot be committed, so an unenabled
hook is still possible. Add a pull_request job running the same scanner
as the backstop that covers everyone regardless.

Document both in .dragon-buddy/README.md rather than README.md, which is
generated wholesale by terraform-docs from docs/.header.md.

This supersedes the ln -sf install line in the previous commit message.
The profile was hand-built because config.example.json was not reachable
at setup time. The pack's actual schema turned up afterwards at
DragonSecurity/dragon-dev-buddy, and the guessed structure diverged:

  - project.stack was a string, the schema wants an array. Any skill
    iterating it would have gotten characters.
  - version, project.repo, practice.lint_command, practice.build_command,
    output.format and voice.avoid were absent entirely.
  - the buddy block used name/mcp_server instead of the schema's
    server/advise_before_work/observe_after_every_skill/skill_prefix.
  - engagement was {} rather than the empty-array shape the skills that
    gate on authorized_scope actually read.

Key parity against config.example.json is now exact in both directions.

output.reports_dir stays .dragon-buddy/reports rather than the schema's
docs/security default: docs/ is tracked here and README.md is generated
from docs/.header.md, so audit reports would end up committed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant