How It Works Features Integrations Pricing Changelog Docs Blog
Request access
Configuration

Writing Custom Rules

Encode your team's security conventions, internal API usage patterns, and domain-specific checks using Gritcadence's YAML rule format. Available on Pro and Team plans.

Rule schema

Each custom rule is a YAML file placed in a directory specified by rules.custom_rules_dir in your .gritcadence.yaml config.

rules/no-direct-db-in-view.yaml
1id: GRCD-CUSTOM-DB-001
2severity: medium
3language: python
4message: Direct DB call in view layer — use repository pattern
5paths:
6 include: ["**/views/**", "**/api/**"]
7pattern-either:
8 - pattern: cursor.execute(...)
9 - pattern: engine.execute(...)
FieldTypeRequiredDescription
idstringYesUnique rule identifier. Recommend GRCD-CUSTOM-XXX-NNN convention.
severityenumYescritical / high / medium / low
languagestringYespython / javascript / typescript / go / java / ruby / rust
messagestringYesShort description shown in PR comment. Max 120 chars.
paths.includestring[]NoGlob patterns to restrict which files this rule applies to.
paths.excludestring[]NoGlob patterns to exclude from this rule.
patternstringNo*Single pattern to match. Use ... as wildcard for arguments.
pattern-eitherstring[]No*List of patterns — fires if any match.
pattern-allstring[]No*List of patterns — fires only if all match in same context.
fixstringNoOptional suggested fix shown in PR comment.

* At least one of pattern, pattern-either, or pattern-all is required.

Test harness

Validate custom rules locally before pushing with the grcd test-rules CLI command (available on Pro/Team plans):

terminal
$ grcd test-rules --rules rules/ --fixtures tests/fixtures/
PASS GRCD-CUSTOM-DB-001 (2 should-match, 1 should-not-match)
PASS GRCD-CUSTOM-AUTH-002 (3 should-match, 2 should-not-match)
All 2 rules passed.

Fixture files use YAML frontmatter to declare expected outcomes:

tests/fixtures/db-in-view.py
1# grcd-test: GRCD-CUSTOM-DB-001
2# should-match: [7]
3# should-not-match: [12]
4
5def get_user(request, user_id):
6 conn = get_connection()
7 cursor.execute(f"SELECT * FROM users WHERE id={user_id}")
8 return cursor.fetchone()

Shared rule libraries (Team plan)

On the Team plan, push custom rules to an org/rules repository and they apply across all repositories in your organization. No per-repo config needed. Rules in the shared library are versioned and auditable.

Custom rule authoring is available on Pro and Team plans. See pricing.