소스 정보
- 저장소
- 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에서 보기