Skip to main content

create-rule

Create a new security rule with all required components

소스 정보

저장소
openshift/cac-content-fork
최근 소스 활동
2026년 3월 26일 15:13
감지된 SKILL.md 언어
영어
스타
6
포크
6

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
create-rule
description
Create a new security rule with all required components
# Create Rule Create a new security rule for ComplianceAsCode. This skill handles both templated and non-templated rules. **Rule ID**: $ARGUMENTS ## Tool Strategy This skill uses `mcp__content-mcp__*` tools when available (preferred — deterministic, structured results). When the MCP server is not configured, fall back to filesystem-based alternatives noted as **Fallback** in each step. See `.claude/skills/shared/mcp_fallbacks.md` for detailed fallback procedures. The skill must complete successfully either way. ## Phase 1: Validate Input 1. **Validate rule ID format**: - Must be lowercase with underscores (no hyphens or uppercase) - Example valid IDs: `sshd_max_auth_tries`, `accounts_password_minlen` 2. **Check if rule already exists**: Use `mcp__content-mcp__search_rules` with `query=$ARGUMENTS` to check if a rule with this ID already exists. **Fallback**: Use `Glob` to search for `**/$ARGUMENTS/rule.yml`. - If rule exists, inform user and ask if they want to modify it instead 3. **Determine rule location**: - Ask user where to create the rule within the guide hierarchy - Provide suggestions based on rule ID prefix (e.g., `sshd_*` goes under `linux_os/guide/services/ssh/ssh_server/`) ## Phase 2: Determine Rule Type Use AskUserQuestion to ask the user: **Question**: "What type of rule do you want to create?" **Options**: 1. **Templated rule (Recommended)** - Uses an existing template for checks and remediations. Faster to create, inherits tests from template. 2. **Non-templated rule** - Custom OVAL, Bash, and Ansible implementations. Requires writing test scenarios. ## Phase 3: Template Selection (if templated) If user chose templated rule: 1. **List available templates** using `mcp__content-mcp__list_templates` to get all available templates with their descriptions. **Fallback**: Run `ls shared/templates/` to list available template directories. 2. **Present available templates** from the list obtained in step 1 and help the user select the right one based on their use case. 3. **Ask for template selection** using AskUserQuestion 4. **Get template parameter schema** using `mcp__content-mcp__get_template_schema` with `template_name=<selected_template>` to get the full parameter schema, supported languages, and documentation. **Fallback**: Read `shared/templates/<template_name>/template.yml` or `template.py` for parameter definitions. Check existing rules using this template for usage examples. 5. **Collect template variables**: - Use the schema from step 4 to identify required and optional parameters - Ask user for each required variable ## Phase 4: Gather Rule Metadata Collect the following information using AskUserQuestion or prompts: ### Required Fields 1. **Title**: Short descriptive title (displayed in scan results) - Example: "Disable SSH Root Login" 2. **Description**: Detailed description using Jinja2 templating - Can use macros like `{{{ sshd_config_file() }}}`, `{{{ describe_mount(...) }}}` 3. **Rationale**: Why this rule is important for security 4. **Severity**: One of `low`, `medium`, `high`, `unknown`. Default value would be `medium`. ### Identifiers 5. **CCE identifiers**: Ask which RHEL products need CCEs (rhel8, rhel9, rhel10) - Format: `cce@rhel9: CCE-XXXXX-X` - **Automatic CCE allocation**: 1. Read available CCEs from `shared/references/cce-redhat-avail.txt` 2. For each requested product, take the first available CCE from the file 3. After adding the CCE to `rule.yml`, remove it from `cce-redhat-avail.txt` to prevent reuse - If user doesn't want CCEs now, leave blank (can be added later) ```bash # Read first available CCE head -1 shared/references/cce-redhat-avail.txt # After using a CCE, remove it from the file sed -i '1d' shared/references/cce-redhat-avail.txt ``` ### References (Optional but Recommended) 6. **Security references** - ask if user has any of: - `nist`: NIST SP 800-53 controls (e.g., `AC-6(2),CM-6(a)`) - `srg`: DISA SRG IDs (e.g., `SRG-OS-000480-GPOS-00227`) - `stigid` and `cis` references are filled in automatically by placing the rule into an appropriate control file ### Additional Fields 7. **Platform** (optional): Platform applicability - Example: `platform: machine` (not for containers) - Example: `platform: package[openssh-server]` 8. **OCIL** (optional): OCIL check description - Often uses macros like `{{{ complete_ocil_entry_sshd_option(...) }}}` ## Phase 5: Generate Rule ### For Templated Rules Use `mcp__content-mcp__generate_rule_from_template` with: - `template_name`: The selected template name - `parameters`: Template variables collected from the user - `rule_id`: $ARGUMENTS - `product`: The target product This generates the rule directory and rule.yml with the template configuration automatically. **Fallback**: Create the rule directory and `rule.yml` manually using `Write` tool. Include the `template:` key with `name:` and `vars:` based on the selected template. ### For Non-Templated Rules Use `mcp__content-mcp__generate_rule_boilerplate` with: - `rule_id`: $ARGUMENTS - `title`: The rule title - `description`: The rule description - `severity`: The severity level - `product`: The target product - `rationale`: The rationale (optional) - `location`: The guide path (optional, e.g., `linux_os/guide/services/ssh`) **Fallback**: Create the directory structure and all files manually using `Write` tool, following the skeleton templates below. This generates the rule directory structure with skeleton files: ``` <location>/$ARGUMENTS/ ├── rule.yml ├── oval/ │ └── shared.xml ├── bash/ │ └── shared.sh ├── ansible/ │ └── shared.yml └── tests/ ├── correct.pass.sh └── wrong.fail.sh ``` ### Post-Generation Customization After MCP generates the boilerplate, customize the generated files: - Add CCE identifiers, references, and platform applicability to rule.yml - For non-templated rules, implement the OVAL, Bash, Ansible, and test content ### Skeleton Files for Non-Templated Rules **oval/shared.xml**: ```xml <def-group> <definition class="compliance" id="{{{ rule_id }}}" version="1"> {{{ oval_metadata("{DESCRIPTION}", rule_title=rule_title) }}} <criteria> <!-- Add OVAL criteria here --> </criteria> </definition> <!-- Add OVAL tests, objects, and states here --> </def-group> ``` Note: `rule_id` and `rule_title` are automatically populated during build from the rule.yml. **bash/shared.sh**: ```bash # platform = multi_platform_all # reboot = false # strategy = configure # complexity = low # disruption = low # Remediation script for $ARGUMENTS # TODO: Implement remediation ``` **ansible/shared.yml**: ```yaml # platform = multi_platform_all # reboot = false # strategy = configure # complexity = low # disruption = low - name: "{TITLE}" # TODO: Implement remediation ansible.builtin.debug: msg: "Remediation not yet implemented" ``` **tests/correct.pass.sh**: ```bash #!/bin/bash # packages = {REQUIRED_PACKAGES} # Set up compliant state # TODO: Configure system to be compliant ``` **tests/wrong.fail.sh**: ```bash #!/bin/bash # packages = {REQUIRED_PACKAGES} # Set up non-compliant state # TODO: Configure system to be non-compliant ``` ## Phase 6: Add to Component Every rule must belong to a component. Components are defined in `components/*.yml` and map rules to their associated packages and groups. ### Step 1: Identify Appropriate Component Based on the rule's purpose and location, suggest likely components: ```bash # List all available components ls components/*.yml | sed 's|components/||;s|\.yml||' | sort ``` **Finding the right component**: Search existing component files for rules with a similar prefix to identify the likely component: ```bash # Find which component contains rules with a similar prefix grep -l '<rule_prefix>' components/*.yml ``` ### Step 2: Verify Component Exists ```bash # Check if suggested component exists cat components/<component_name>.yml ``` ### Step 3: Ask User to Confirm or Select Component Use AskUserQuestion with options: 1. Suggested component (if identified) 2. Browse/search for another component 3. Create a new component ### Step 4a: Add Rule to Existing Component If user selects an existing component: 1. **Read the component file**: ```bash cat components/<component_name>.yml ``` 2. **Add the rule ID** to the `rules:` list in alphabetical order: ```yaml rules: - existing_rule_1 - existing_rule_2 - $ARGUMENTS # Add new rule here - existing_rule_3 ``` 3. **If using a template**, verify the template is listed in `templates:` section. If not, add it: ```yaml templates: - existing_template - {TEMPLATE_NAME} # Add if not present ``` ### Step 4b: Create New Component If no suitable component exists: 1. **Ask for component details**: - Component name (lowercase, hyphenated, e.g., `my-service`) - Associated packages (list) - Associated groups (from rule hierarchy) 2. **Create the component file** `components/<component_name>.yml`: ```yaml groups: - <group_from_rule_hierarchy> name: <component_name> packages: - <package_name> rules: - $ARGUMENTS templates: - {TEMPLATE_NAME} # If templated rule ``` 3. **Verify the new component**: ```bash python3 -c "import yaml; yaml.safe_load(open('components/<component_name>.yml'))" ``` ### Component File Structure Reference ```yaml groups: # Rule groups this component covers (from guide hierarchy) - service_name - service_name_server name: component-name # Matches filename without .yml packages: # Packages associated with this component - package-name - package-name-server rules: # Rule IDs belonging to this component (alphabetical) - rule_id_1 - rule_id_2 templates: # Templates used by rules in this component - template_name ``` ## Phase 7: Add to Profile(s) or Control File(s) Most profiles in the project reference control files rather than listing rules directly. When adding a rule to a profile that uses a control file, add the rule to the control file instead. ### Step 1: List Available Profiles Use `mcp__content-mcp__list_profiles` with `product=<product>` to list all available profiles for each target product. **Fallback**: Run `ls products/<product>/profiles/*.profile` to list profiles. ### Step 2: Ask User Which Profile(s) Use AskUserQuestion to ask which profile(s) to add the rule to. Allow multiple selection. ### Step 3: Detect Control File Reference For each selected profile, read it and check if it references a control file: ```bash grep -E "^\s+-\s+\w+:all" products/<product>/profiles/<profile>.profile ``` **Control file reference patterns**: - `cis_rhel9:all` or `cis_rhel9:all:l2_server` → Control file: `products/rhel9/controls/cis_rhel9.yml` - `stig_rhel9:all` → Control file: `products/rhel9/controls/stig_rhel9.yml` - `hipaa:all` → Control file: `controls/hipaa.yml` (shared across products) **How to find the control file**: 1. Extract the control ID from the selection (e.g., `cis_rhel9` from `cis_rhel9:all:l2_server`) 2. Look in `products/<product>/controls/<control_id>.yml` first 3. If not found, look in `controls/<control_id>.yml` ### Step 4a: Add to Control File (if profile uses control file) If the profile references a control file: 1. **Read the control file** to understand its structure 2. **Ask user for control placement**: - For CIS: Ask for the section ID (e.g., `5.2.15` for SSH settings) - For STIG: Ask for the STIG ID (e.g., `RHEL-09-123456`) - Show the control file structure to help user decide 3. **Determine the level(s)** for the rule: - CIS: `l1_server`, `l2_server`, `l1_workstation`, `l2_workstation` - STIG: `high`, `medium`, `low` 4. **Add a new control entry** to the control file: **For CIS control files**: ```yaml - id: 5.2.15 title: Ensure SSH MaxAuthTries is set to 4 or less (Automated) levels: - l1_server - l1_workstation status: automated rules: - $ARGUMENTS ``` **For STIG control files**: ```yaml - id: RHEL-09-123456 levels: - medium title: RHEL 9 must limit the number of SSH authentication attempts. rules: - $ARGUMENTS status: automated ``` 5. **Insert in the correct position** (controls are typically ordered by ID) ### Step 4b: Add Directly to Profile (if no control file) If the profile lists rules directly (no control file reference): 1. Read the profile file 2. Add the rule ID to the `selections:` list 3. Maintain alphabetical order if the profile uses it ### Control File Locations **Product-specific** (preferred for product-specific benchmarks): - `products/rhel8/controls/*.yml` - `products/rhel9/controls/*.yml` - `products/rhel10/controls/*.yml` **Shared** (for cross-product policies): - `controls/*.yml` ### Common Control Files by Profile | Profile | Control File |
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기