Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions skills/software-security/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,20 @@ When writing or reviewing code:
- `codeguard-1-hardcoded-credentials.md` - Never hardcode secrets, passwords, API keys, or tokens
- `codeguard-1-crypto-algorithms.md` - Use only modern, secure cryptographic algorithms
- `codeguard-1-digital-certificates.md` - Validate and manage digital certificates securely
2. Context-Specific Rules: Apply rules from /rules directory based on the language of the feature being implemented using the table given below:
2. Tag-Based Rules: When you identify any of these security contexts in the code, apply ALL rules with the matching tag:


| Security Context (Tag) | Rule Files to Apply |
|------------------------|---------------------|
| authentication | codeguard-0-authentication-mfa.md, codeguard-0-session-management-and-cookies.md |
| data-security | codeguard-0-additional-cryptography.md, codeguard-0-data-storage.md |
| infrastructure | codeguard-0-cloud-orchestration-kubernetes.md, codeguard-0-data-storage.md, codeguard-0-devops-ci-cd-containers.md, codeguard-0-iac-security.md |
| privacy | codeguard-0-logging.md, codeguard-0-privacy-data-protection.md |
| secrets | codeguard-0-additional-cryptography.md, codeguard-1-digital-certificates.md, codeguard-1-hardcoded-credentials.md |
| web | codeguard-0-api-web-services.md, codeguard-0-authentication-mfa.md, codeguard-0-client-side-web-security.md, codeguard-0-input-validation-injection.md, codeguard-0-session-management-and-cookies.md |


3. Language-Specific Rules: Apply rules from /rules directory based on the programming language of the feature being implemented using the table given below:


| Language | Rule Files to Apply |
Expand Down Expand Up @@ -55,7 +68,7 @@ When writing or reviewing code:
| yaml | codeguard-0-additional-cryptography.md, codeguard-0-api-web-services.md, codeguard-0-authorization-access-control.md, codeguard-0-cloud-orchestration-kubernetes.md, codeguard-0-data-storage.md, codeguard-0-devops-ci-cd-containers.md, codeguard-0-framework-and-languages.md, codeguard-0-iac-security.md, codeguard-0-logging.md, codeguard-0-privacy-data-protection.md, codeguard-0-supply-chain-security.md |


3. Proactive Security: Don't just avoid vulnerabilities-actively implement secure patterns:
4. Proactive Security: Don't just avoid vulnerabilities-actively implement secure patterns:
- Use parameterized queries for database access
- Validate and sanitize all user input
- Apply least-privilege principles
Expand All @@ -71,8 +84,8 @@ When generating or reviewing code, follow this workflow:
### 1. Initial Security Check
Before writing any code:
- Check: Will this handle credentials? → Apply codeguard-1-hardcoded-credentials
- Check: What security tags apply? → Load all rules with matching tags (e.g., "authentication", "web", "secrets")
- Check: What language am I using? → Identify applicable language-specific rules
- Check: What security domains are involved? → Load relevant rule files

### 2. Code Generation
While writing code:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ languages:
- xml
- yaml
alwaysApply: false
tags:
- data-security
- secrets
---

rule_id: codeguard-0-additional-cryptography
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ languages:
- xml
- yaml
alwaysApply: false
tags:
- web
---

rule_id: codeguard-0-api-web-services
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ languages:
- swift
- typescript
alwaysApply: false
tags:
- authentication
- web
---

rule_id: codeguard-0-authentication-mfa
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ languages:
- typescript
- vlang
alwaysApply: false
tags:
- web
---

rule_id: codeguard-0-client-side-web-security
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ languages:
- javascript
- yaml
alwaysApply: false
tags:
- infrastructure
---

rule_id: codeguard-0-cloud-orchestration-kubernetes
Expand Down
3 changes: 3 additions & 0 deletions skills/software-security/rules/codeguard-0-data-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ languages:
- sql
- yaml
alwaysApply: false
tags:
- data-security
- infrastructure
---

rule_id: codeguard-0-data-storage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ languages:
- xml
- yaml
alwaysApply: false
tags:
- infrastructure
---

rule_id: codeguard-0-devops-ci-cd-containers
Expand Down
2 changes: 2 additions & 0 deletions skills/software-security/rules/codeguard-0-iac-security.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ languages:
- shell
- yaml
alwaysApply: false
tags:
- infrastructure
---

rule_id: codeguard-0-iac-security
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ languages:
- sql
- typescript
alwaysApply: false
tags:
- web
---

rule_id: codeguard-0-input-validation-injection
Expand Down
2 changes: 2 additions & 0 deletions skills/software-security/rules/codeguard-0-logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ languages:
- javascript
- yaml
alwaysApply: false
tags:
- privacy
---

rule_id: codeguard-0-logging
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ languages:
- matlab
- yaml
alwaysApply: false
tags:
- privacy
---

rule_id: codeguard-0-privacy-data-protection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ languages:
- ruby
- typescript
alwaysApply: false
tags:
- authentication
- web
---

rule_id: codeguard-0-session-management-and-cookies
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
description: Certificate Best Practices
alwaysApply: true
tags:
- secrets
---

rule_id: codeguard-1-digital-certificates
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
description: No Hardcoded Credentials
alwaysApply: true
tags:
- secrets
---

rule_id: codeguard-1-hardcoded-credentials
Expand Down
9 changes: 6 additions & 3 deletions sources/rules/core/codeguard-SKILLS.md.template
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ When writing or reviewing code:
- `codeguard-1-hardcoded-credentials.md` - Never hardcode secrets, passwords, API keys, or tokens
- `codeguard-1-crypto-algorithms.md` - Use only modern, secure cryptographic algorithms
- `codeguard-1-digital-certificates.md` - Validate and manage digital certificates securely
2. Context-Specific Rules: Apply rules from /rules directory based on the language of the feature being implemented using the table given below:
2. Tag-Based Rules: When you identify any of these security contexts in the code, apply ALL rules with the matching tag:
<!-- TAG_MAPPINGS_START -->
<!-- TAG_MAPPINGS_END -->
3. Language-Specific Rules: Apply rules from /rules directory based on the programming language of the feature being implemented using the table given below:
<!-- LANGUAGE_MAPPINGS_START -->
<!-- LANGUAGE_MAPPINGS_END -->
3. Proactive Security: Don't just avoid vulnerabilities-actively implement secure patterns:
4. Proactive Security: Don't just avoid vulnerabilities-actively implement secure patterns:
- Use parameterized queries for database access
- Validate and sanitize all user input
- Apply least-privilege principles
Expand All @@ -43,8 +46,8 @@ When generating or reviewing code, follow this workflow:
### 1. Initial Security Check
Before writing any code:
- Check: Will this handle credentials? → Apply codeguard-1-hardcoded-credentials
- Check: What security tags apply? → Load all rules with matching tags (e.g., "authentication", "web", "secrets")
- Check: What language am I using? → Identify applicable language-specific rules
- Check: What security domains are involved? → Load relevant rule files

### 2. Code Generation
While writing code:
Expand Down
46 changes: 46 additions & 0 deletions src/convert_to_ide_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,45 @@ def update_skill_md(language_to_rules: dict[str, list[str]], skill_path: Path) -
print(f"Updated SKILL.md with language mappings")


def update_tag_mappings(tag_to_rules: dict[str, list[str]], skill_path: Path) -> None:
"""
Update SKILL.md with tag-to-rules mapping table.

Args:
tag_to_rules: Dictionary mapping tags to rule files
skill_path: Path to SKILL.md file
"""
table_lines = [
"| Security Context (Tag) | Rule Files to Apply |",
"|------------------------|---------------------|",
]

for tag in sorted(tag_to_rules.keys()):
rules = sorted(tag_to_rules[tag])
rules_str = ", ".join(rules)
table_lines.append(f"| {tag} | {rules_str} |")

table = "\n".join(table_lines)

start_marker = "<!-- TAG_MAPPINGS_START -->"
end_marker = "<!-- TAG_MAPPINGS_END -->"

content = skill_path.read_text(encoding="utf-8")

if start_marker not in content or end_marker not in content:
# Markers are optional; skip silently so older templates still work.
print("Note: tag mappings markers not found in SKILL.md; skipping tag table")
return

start_idx = content.index(start_marker)
end_idx = content.index(end_marker) + len(end_marker)
new_section = f"\n\n{table}\n\n"
updated_content = content[:start_idx] + new_section + content[end_idx:]

skill_path.write_text(updated_content, encoding="utf-8")
print(f"Updated SKILL.md with tag mappings")


def convert_rules(
input_path: str,
output_dir: str = "dist",
Expand Down Expand Up @@ -182,6 +221,7 @@ def convert_rules(

results = {"success": [], "errors": [], "skipped": []}
language_to_rules = defaultdict(list)
tag_to_rules = defaultdict(list)

# Process each file
for md_file in md_files:
Expand Down Expand Up @@ -220,6 +260,9 @@ def convert_rules(
for language in result.languages:
language_to_rules[language].append(result.filename)

for tag in result.tags:
tag_to_rules[tag].append(result.filename)

except FileNotFoundError as e:
error_msg = f"{md_file.name}: File not found - {e}"
print(f"Error: {error_msg}")
Expand Down Expand Up @@ -269,6 +312,9 @@ def convert_rules(

update_skill_md(language_to_rules, output_skill_path)

if tag_to_rules:
update_tag_mappings(tag_to_rules, output_skill_path)

for host_dir in SKILL_COPY_HOSTS:
host_skill_dir = Path(output_dir) / host_dir / "skills" / "software-security"
host_skill_dir.mkdir(parents=True, exist_ok=True)
Expand Down
12 changes: 9 additions & 3 deletions src/formats/agentskills.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ def generate(self, rule: ProcessedRule, globs: str) -> str:
"""
Generate Agent Skills .md format.

Agent Skills should preserve the original YAML frontmatter
(description, languages, alwaysApply) so the rules remain complete
and can be referenced properly by AI coding agents.
Agent Skills preserves the original YAML frontmatter (description,
languages, alwaysApply, tags) so the rules remain complete and can
be referenced properly by AI coding agents.

Args:
rule: The processed rule to format
Expand All @@ -70,4 +70,10 @@ def generate(self, rule: ProcessedRule, globs: str) -> str:
# Add alwaysApply
yaml_lines.append(f"alwaysApply: {str(rule.always_apply).lower()}")

# Add tags as expanded YAML list (preserves the source format)
if rule.tags:
yaml_lines.append("tags:")
for tag in rule.tags:
yaml_lines.append(f"- {tag}")

return self._build_yaml_frontmatter(yaml_lines, rule.content)
5 changes: 5 additions & 0 deletions src/formats/antigravity.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class AntigravityFormat(BaseFormat):
- globs: (if trigger is 'glob') File matching patterns
- description: Rule description
- version: Rule version
- tags: (optional) List of categorization tags

Rules use activation types (Always On or Glob) to determine when
they apply, similar to Windsurf's implementation.
Expand Down Expand Up @@ -70,4 +71,8 @@ def generate(self, rule: ProcessedRule, globs: str) -> str:
# Add version
yaml_lines.append(f"version: {self.version}")

if rule.tags:
tags_str = ", ".join(rule.tags)
yaml_lines.append(f"tags: [{tags_str}]")

return self._build_yaml_frontmatter(yaml_lines, rule.content)
7 changes: 6 additions & 1 deletion src/formats/copilot.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ class CopilotFormat(BaseFormat):

Copilot uses .instructions.md files with YAML frontmatter containing:
- applyTo: File matching patterns
- title: Rule title/description
- description: Rule description
- version: Rule version
- tags: (optional) List of categorization tags
"""

def get_format_name(self) -> str:
Expand Down Expand Up @@ -53,4 +54,8 @@ def generate(self, rule: ProcessedRule, globs: str) -> str:
# Add version
yaml_lines.append(f"version: {self.version}")

if rule.tags:
tags_str = ", ".join(rule.tags)
yaml_lines.append(f"tags: [{tags_str}]")

return self._build_yaml_frontmatter(yaml_lines, rule.content)
5 changes: 5 additions & 0 deletions src/formats/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class CursorFormat(BaseFormat):
- globs: File matching patterns
- version: Rule version
- alwaysApply: (optional) Whether to apply to all files
- tags: (optional) List of categorization tags
"""

def get_format_name(self) -> str:
Expand Down Expand Up @@ -56,4 +57,8 @@ def generate(self, rule: ProcessedRule, globs: str) -> str:
if rule.always_apply:
yaml_lines.append("alwaysApply: true")

if rule.tags:
tags_str = ", ".join(rule.tags)
yaml_lines.append(f"tags: [{tags_str}]")

return self._build_yaml_frontmatter(yaml_lines, rule.content)
5 changes: 5 additions & 0 deletions src/formats/windsurf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class WindsurfFormat(BaseFormat):
- globs: (if trigger is 'glob') File matching patterns
- title: Rule title/description
- version: Rule version
- tags: (optional) List of categorization tags
"""

def get_format_name(self) -> str:
Expand Down Expand Up @@ -58,4 +59,8 @@ def generate(self, rule: ProcessedRule, globs: str) -> str:
# Add version
yaml_lines.append(f"version: {self.version}")

if rule.tags:
tags_str = ", ".join(rule.tags)
yaml_lines.append(f"tags: [{tags_str}]")

return self._build_yaml_frontmatter(yaml_lines, rule.content)
Loading