Policy Development
Introduction
The Compliance Engine is designed to store all entities as files. To maintain a proper development process, these files and directories are stored in a Git repository.
Cloudaware maintains a public Compliance Engine repository containing all up-to-date policies, which is used by default when subscribing to the Compliance Engine service.
It is also possible to host your own private repository and connect it to Cloudaware for developing and hosting custom policies and other customizations. See Private Repository documentation.
This document outlines the structure of the policy repository and provides best practices for developing effective and maintainable Compliance Engine policies. Remember that policy development is not just about writing "code"; it's about declaratively defining compliance rules in a clear, understandable, and maintainable way.
Repository Structure
You can host any files in your repository, not just Compliance Engine entities. When developing policies, we encourage storing supplementary materials like screenshots, internal notes, and downloaded external documentation to provide context and intent for future maintenance and updates.
Key root-level directories include:
/ce: Root folder for all policies, containing subfolders:/ce/ca: Stores Cloudaware's public policies/ce/unit-test: Contains unit tests for Compliance Engine operations- (Create custom folders here for internal policies)
/frameworks: Root directory for compliance frameworks (subdirectories represent individual frameworks)/schema: Local copies of JSON schemas for.yamlfiles (used for IDE validation/autocomplete). See commandrepo-manager schemato update the schema/types: Local copies of SObject type definitions (seerepo-manager types)/types/types.json: List of all types available in the organization (updates with any call torepo-manager types import)/export: Default output directory forrepo-manager export/lists: Contains tagged entity lists generated byrepo-manager docs(useful for tracking WIP policies, policies missing documentation, tests, etc.)/.ca: Storesrepo-managerconfiguration and authorization data/.docusaurus: Contains Docusaurus configuration for generating static documentation/.vscode: Preconfigured settings for VSCode recommended extensions (see VSCode Configuration))
Path Notation Guidelines:
- Compliance Engine uses Linux-style paths (
/) regardless of OS- Root directory is referenced as
/- Absolute paths are preferred (e.g.,
/ce/ca/aws/ec2)- Relative paths are used in some cases (e.g.
test-data.json)- Folder paths omit trailing slashes (e.g.,
/ce/ca/aws/ec2instead of/ce/ca/aws/ec2/)
Folder
Folders organize policies and subfolders within the /ce folder.
Directory vs Folder:
- Directory: Physical filesystem container, used when we refer to the directory where
folder.yaml,policy.yamlorsection.yamlis stored.- Folder: Refers to folder as entity, a directory containing a
folder.yamldescriptor file, a logical container for policies
All /ce subfolders must contain either folder.yaml or policy.yaml.
Folder ID: Absolute path to directory containing folder.yaml (e.g., for descriptor /ce/ca/aws/ec2/folder.yaml, Folder ID is /ce/ca/aws/ec2)
folder.yaml Structure:
names: Contains display names:contextual: Name shown in hierarchical contextsfull: Name shown in isolation
Example Hierarchy:
| Path | Contextual Name | Full Name |
|---|---|---|
/ce | Compliance Engine | Compliance Engine |
/ce/ca | CloudAware | CloudAware |
/ce/ca/aws | AWS | AWS |
/ce/ca/aws/ec2 | AWS EC2 | EC2 |
Policy
A policy in the Compliance Engine represents a specific rule or idea you want to test against your cloud environment. Think of a policy as a declarative description of a compliance requirement, not imperative code. It embodies an idea, while logic is the implementation of that idea.
A policy is not the same as logic. A policy embodies an idea, while logic is the implementation of that idea. Some policies can have multiple logic implementations, one of which can be accepted as production logic. Some policies might not have any logic implemented, either because they are not yet implemented or because they are fundamentally unimplementable due to API limitations, for example. These policies are marked with an impossible: true flag. However, it's important to keep these policies in the repository as they capture all the research done, which could be beneficial if the policy becomes implementable in the future. You might also have non-technical methods to check for compliance; in such cases, you can reference the Policy ID in external systems to combine Compliance Engine violations with external data for a complete compliance picture.
Policies serve as collaboration points between teams. For example:
- Security team can define compliance requirements through policy documentation
- Engineering team can develop corresponding logic implementations
- Cross-functional teams can reference Policy IDs in external systems for holistic compliance tracking
In this scenario, security team does not need knowledge of Cloudaware CMDB, Compliance Engine, or any other Cloudaware-specific knowledge.
Policy ID: Absolute path to directory containing policy.yaml (e.g., for descriptor /ce/ca/aws/account/config-in-all-regions/policy.yaml, Policy ID is /ce/ca/aws/account/config-in-all-regions)
Each policy directory contains these key files:
policy.yaml(Required): Descriptor file with these notable properties:names: Display names (fullfor standalone contexts,contextualfor hierarchical views)description: Concise summary (1-2 sentences without formatting)impossible: Flag for technically unenforceable policiestype: Policy classification (COMPLIANCE_POLICY/BEST_PRACTICE). Refer toPolicyTypein the schemacategories: Compliance dimensions (SECURITY,RELIABILITY,PERFORMANCE,COST). Refer toPolicyCategoryin the schemaframeworkMappings: List of framework section IDs that this policy directly maps toframeworkIgnoreMappings: List of framework section IDs to be ignored if the policy maps to them indirectly throughsimilarPoliciessimilarPolicies: Cross-references to external vendors like AWS Trusted Advisor, AWS Security Hub, etc.tags: An arbitrary list of string for custom classification
description.md: Detailed technical specification typically containing:- Rationale: Business/security justification
- Impact: Potential risks of non-compliance
- Audit: Manual verification procedures (Console/CLI)
- References: Supporting documentation
remediation.md: Mitigation guidance with:- Step-by-step resolution procedures
- Console/CLI remediation paths
- Configuration best practices
todo.md: Implementation roadmap/tasks, listed in/listsinternal.md: Developer notes (algorithms, edge cases, debug info), listed in/lists{name}.logic.yamlLogic implementations.{name}can be any string, some reserved names have special behaviors:prod.logic.yaml: Production logic executed by Compliance Engine (see Logic). This logic should be thoroughly tested and validated.wip.logic.yaml: Development-stage logic, listed in/listsunit-test.logic.yaml: Unit tests for Compliance Engineexample.logic.yaml: Reference implementations
Best practices:
- Store supporting materials (screenshots, API docs) locally with policies
- Maintain complete implementation context within the repository
- Use standardized documentation sections for maintainability
- Preserve historical research through
impossiblepolicies - Rethink, don't just rewrite policies: Critically evaluate existing policies. Ensure they are relevant, make sense, and fully utilize all possible statuses (
COMPLIANT,INCOMPLIANT,INAPPLICABLE,UNDETERMINED). - Write comprehensive comments: Document the policy's purpose, implementation details, research findings, and any important notes for future developers. Aim for a high ratio of comments to policy logic.
Logic
A logic file ({name}.logic.yaml) contains the actual instructions for the Compliance Engine on how to validate input objects and assign appropriate compliance statuses. Remember, logic is declarative, describing how to determine status, not procedurally what to do.
Logic ID: The absolute path to the {name}.logic.yaml file (e.g., /ce/ca/aws/account/config-in-all-regions/prod.logic.yaml).
The {name}.logic.yaml file contains these key properties:
inputType: (Required) Specifies the API name of the object in the Cloudaware CMDB that this logic will evaluate, such asCA10__CaAwsInstance__c.recordTypes: (Optional) Filters evaluation to specific Record Types when theinputTypesupports multiple types.testData: (Optional) Path to test data files (e.g., localtest-data.json, relative../test-data.json, or absolute paths). Used for validation during testing.importExtracts: (Optional) References to reusable data extraction rules. See Extracts section for details.conditions: (Required) Ordered list of validation checks. The first condition's check returningtruedetermines the object's status. Design conditions to be small and focused for better readability and maintainability.otherwise: (Required) Fallback status assigned if no conditions match.relatedLists: (Optional) Nested validations for related objects via CMDB relationships. See Related Lists for details.
Conditions
Each condition represents a discrete check that assigns a status if its evaluation returns true. Conditions are evaluated sequentially until a match occurs.
Best practices:
- Prioritize specific conditions first to enable early exits
- Use targeted operations like
NOT_EQUALinstead of nested operations likeNOTwithIS_EQUALorRELATED_LIST_HASinstead ofGREATER_THANwithRELATED_LIST_COUNT - Leverage IDE validation through JSON schemas (Ctrl/Cmd+Space in VSCode)
- Break down complex checks into smaller, more manageable conditions. This improves readability, maintainability, and allows for more precise status and remediation messages.
- Use code suggestion (Ctrl+Space) while writing the policy. Schema is always up-to-date with available functionality.
Condition structure:
status: Compliance status to assign (DISAPPEARED,INAPPLICABLE,COMPLIANT,INCOMPLIANT, orUNDETERMINED). Refer toStatusin the schemacurrentStateMessage: Brief description of the object's state (1 sentence, no formatting recommended). Write clear and concise messages that are specific to the condition.remediationMessage: Actionable guidance forINCOMPLIANTstatus or reference toremediation.md(omit for other statuses). Keep remediation messages brief and reference detailed instructions inremediation.md.check: Boolean operation defining the check. Choose the most appropriate operation for the task. Consult the schema and use code completion in your IDE to explore available operations.
Status definitions:
DISAPPEARED: Automatically assigned to objects removed at the source but still in CMDB (detected via non-empty "Deleted from ..."/CA10__disappearanceTime__cfields)INAPPLICABLE: Indicates the policy doesn't apply to this object variant (e.g., non-root IAM users in account-level policies)COMPLIANT: Confirmed adherence to policy requirementsINCOMPLIANT: Verified policy violationUNDETERMINED: Insufficient data for conclusive evaluation. UseUNDETERMINEDwhen data might be missing due to permissions, API limits, or data inconsistencies. Aim to minimize false positives/negatives by explicitly handling these scenarios.
The Compliance Engine prioritizes minimizing false positives/negatives. Built-in policies account for common data inconsistencies caused by:
- Limited collector permissions
- Outdated credential configurations
- Retained decommissioned accounts
- API throttling limitations
- Partial data collection due to polling constraints
When fields required for evaluation might be unpopulated, policies should explicitly handle these scenarios by returning UNDETERMINED.
Related Lists
Related lists enable multi-level validation through object relationships. Key differences from root logic:
- Uses
relationshipNameinstead ofinputType(supports relationship chains likeCA10__vpcSubnet__r.CA10__routeTableAssociations__r) - Excludes
testDatasupport. Related objects are tested with their parent object - Maintains identical structure for
conditions,otherwise, and nestedrelatedLists
Related list evaluations produce aggregated results usable in parent logic through operations like:
RELATED_LIST_HASRELATED_LIST_HAS_NORELATED_LIST_COUNT- etc., see Operations list for details. Choose the appropriate aggregate operation based on your validation needs.
Extracts
Extracts help reduce clutter and code repetition in policies by providing validated, reusable pieces of information extracted from input objects. Prioritize using EXTRACT over direct FIELD operations in production policies for abstraction, reusability, and maintainability. While FIELD may be used during development for convenience, production policies should never contain FIELD references. This is because using EXTRACT provides several benefits, including:
- Abstraction: isolating logic from direct field names, making policies more resilient to CMDB changes
- Reusability: extracts can be shared across policies
- Maintainability: centralizing field access logic in extract definitions
Extract definitions are stored in /types/{type}/{name}.extracts.yaml files. To use an extract in logic:
- Add an
importExtractsreference in your logic file - Reference the extract using
EXTRACT: "{extractName}"
Naming conventions:
-
Field wrappers: When enhancing existing fields with additional checks, name the extract file
/types/{type}/object.extracts.yamland match the extract name to the original field name. Example:- File:
/types/CA10__CaAwsInstance__c/object.extracts.yaml - Usage:
EXTRACT: "CA10__monitoringState__c"
- File:
-
Cross-object consistency: Use identical extract names for equivalent data across different objects. Example:
- File:
/types/CA10__CaAwsInstance__c/breeze.extracts.yaml. Extract name:CA10__breezeLastUpdate__c - File:
/types/CA10__CaAzureVirtualMachine__c/breeze.extracts.yaml. Extract name:CA10__breezeLastUpdate__c
- File:
-
JSON field handling: When extracting multiple values from a JSON field, create a dedicated
{name}.extracts.yamlfile containing all related extracts.
Cloudaware maintains comprehensive extracts for all managed CMDB objects. If your policy requires an extract that doesn't exist, contact your Technical Account Manager to request its creation.
Test Data
Test data consists of JSON files (typically named test-data.json) used by the repo-manager policies test command to validate policy logic implementations. This command produces {logicName}.test-results.yaml files that store test results in the repository for later documentation generation.
Test Data ID: The absolute path to the test data file (e.g., /ce/ca/aws/account/config-in-all-regions/test-data.json).
These JSON files are typically captured after completing policy logic development to prevent regression errors. The standard workflow involves:
- Using
repo-manager policies generate CAPTURE_TEST_DATAto create SQL queries - Executing generated SQL through the "BigQuery Runner" VSCode plugin (see VSCode Configuration)
- Saving query results in JSON format
While manual creation of test data files is possible, we recommend capturing real-world data first and then modifying the JSON to:
- Add synthetic test objects
- Cover all logic conditions
- Simulate edge cases
Test data files are typically stored in the policy directory alongside policy.yaml and referenced in logic files via relative path (test-data.json). Alternative storage locations require absolute or relative path references in the testData property.
File structure:
[
{
"expectedResult": {
"status": "INAPPLICABLE",
"conditionIndex": "199",
"conditionText": "extract('CA10__stateName__c') != 'running'",
"runtimeError": null
},
"context": {
"snapshotTime": "2024-11-20T19:21:48Z"
},
"Id": "test2",
"CA10__disappearanceTime__c": null,
"CA10__stateName__c": "stopped",
"CA10__monitoringState__c": "disabled"
}
]
Key components:
expectedResult: Defines validation criteriastatus: Required compliance statusconditionIndex: Index of matching condition group. The condition from yourlogic.yamlfile will have an index ending in99. Indexes ending in01,02, etc., represent implicit conditions.conditionText: Human-readable condition logicruntimeError: Runtime error (e.g., when testing invalid JSON) ornull
context: Execution parameterssnapshotTime: Simulation timestamp for time-sensitive validations
- Field values: Object properties required for logic evaluation (only includes fields referenced in policy conditions)
Section
A Section represents an individual numbered or named component within a compliance framework. The root section of a framework is itself considered a section.
Frameworks are stored in the /frameworks directory. Each directory represents the root node of a framework, and each subdirectory corresponds to a section within that framework.
All sections, including the framework root itself, must contain a descriptor file named section.yaml.
Section ID: Absolute path to the directory containing section.yaml (e.g., for descriptor /frameworks/nist-sp-800-53-r5/ac/01/section.yaml, the Section ID is /frameworks/nist-sp-800-53-r5/ac/01).
section.yaml Structure:
name: Full section name (equivalent to policy'snames.fullproperty). For root framework sections, this should match the framework name.description: Official section description from framework documentationsinglePolicyOnly: Set totrueifrepo-managershould flag sections with multiple attached policies in/lists. Useful for frameworks requiring strict 1:1 policy-to-section mappings like CIS Foundations benchmarks.similar: Cross-references to equivalent sections in other frameworks:sections: List of Section IDs from this repositoryinternal: Cloudaware internal mappingsawsSecurityHub: AWS Security Hub mappingscontrolUrl: Control reference by URL
Sections inherit all policies from referenced similar sections. This mechanism is particularly useful for mapping equivalent requirements across different frameworks or framework versions.
Type
Directories within the /types directory are named after the API names of SObjects in the Cloudaware CMDB (e.g., CA10__CaAwsInstance__c).
Type ID: The absolute path to the directory containing type.json or *.extracts.yaml files (e.g., /types/CA10__CaAwsInstance__c).
Type directories serve several purposes:
- Storing extract files
- Providing local references for available fields, lookups, relationships, etc. through generated documentation
- Serving as reference points for other repository entities in generated documentation
Each type directory contains the following files:
/types/{type}/type.json: Object definition downloaded from your Cloudaware CMDB using therepo-manager types importcommand. This file should not be manually created or edited by the user./types/{type}/{name}.extracts.yaml: Extract definitions available for this object type. See the Extracts section for details.
Naming Conventions
The Compliance Engine enforces structured naming conventions to ensure consistency, discoverability, and interoperability across policies, frameworks, and related artifacts.
These conventions enable automated documentation generation, cross-policy references, and compatibility with Cloudaware's validation toolchain. Adherence ensures proper functioning of the repo-manager utilities and CI/CD integration.
Directory & File Naming
Policy Repository Structure
-
Root directories: Use predefined names with specific purposes:
/ce: Contains all policy hierarchies/frameworks: Stores compliance framework definitions/types: Houses CMDB object type definitions/schema,/export,/lists: Follow exact naming for tooling compatibility
-
Policy paths: Use lowercase letters with hyphens to separate words in directory names:
/ce/ca/aws/ec2/instance-detailed-monitoring -
Special directories: Reserved names with specific behaviors:
/ce/unit-test: Contains policy validation tests/.ca,/.docusaurus,/.vscode: Configuration directories
Descriptor Files
| File Type | Naming Pattern | Requirement |
|---|---|---|
| Folder descriptor | folder.yaml | Mandatory |
| Policy descriptor | policy.yaml | Mandatory |
| Section descriptor | section.yaml | Mandatory |
| Type definition | type.json | Auto-generated |
| Extract definition | {purpose}.extracts.yaml | Context-dependent |
Policy Components
Logic Implementations
Use reserved names for special logic files:
prod.logic.yaml: Production-grade implementationwip.logic.yaml: Work-in-progress logicunit-test.logic.yaml: Validation testsexample.logic.yaml: Reference implementations
prod.logic.yaml - Production Logic
The prod.logic.yaml file represents the production-grade logic implementation for a policy. This is the logic that will be executed by the Compliance Engine in a production environment. Ensure prod.logic.yaml is thoroughly tested and validated for accuracy and reliability before deployment. See Logic for details on logic file structure.
Display Names
Define dual naming in YAML descriptors:
names:
full: AWS EC2 Instance Detailed Monitoring is not enabled
contextual: Instance Detailed Monitoring is not enabled
- Full: Standalone display name
- Contextual: Shown in hierarchical displays
Framework Organization
-
Root directory: Matches framework's official abbreviation:
/frameworks/nist-sp-800-53-r5 -
Section paths: Follow framework's section numbering/naming scheme:
/frameworks/cis-aws-foundations-benchmark/01/01- Always use leading zeroes to maintain 2-digit numbering (e.g.,
01instead of1) - For frameworks with over 100 subsections, use 3-digit numbering (e.g.,
001)
- Always use leading zeroes to maintain 2-digit numbering (e.g.,
CMDB Object Types
-
Type directories: Exact API names with namespace:
/types/CA10__CaAwsInstance__c -
Extract files: Context-specific naming patterns:
- Field wrappers:
object.extracts.yaml - Cross-object consistency:
breeze.extracts.yaml - JSON processing:
{field-name}.extracts.yaml
- Field wrappers:
Test Data
- Primary test data:
test-data.json(stored in policy directory) - Alternate locations: Reference via absolute path (e.g.,
/ce/my-company/tagging/test-data.json) or relative path (e.g.,../shared-test-data.json)
ID Construction
All entities use absolute Linux-style paths as unique identifiers:
| Entity Type | ID Example |
|---|---|
| Folder | /ce/ca/aws/ec2 |
| Policy | /ce/ca/aws/ec2/instance-detailed-monitoring |
| Logic | /ce/ca/aws/ec2/instance-detailed-monitoring/prod.logic.yaml |
| Section | /frameworks/nist-sp-800-53-r5/ac/01 |
| Type | /types/CA10__CaAwsInstance__c |
Documentation Generation
While the files in the repository are human-readable, they lack functionality for developers to easily navigate between different entities. Tasks such as:
- Finding other policies that evaluate the same object
- Locating policies linked to framework sections
- Reviewing test results
- Identifying incomplete policies requiring updates
- And more
are nearly impossible without generated documentation.
The primary command for documentation generation is repo-manager docs generate. This command analyzes the entire repository and produces *.gen.md files in the same directories as descriptor files and other entities. Documentation is generated for both permanent files (like policy.yaml) and temporary files (excluded via default /.gitignore, such as {logicName}.test-results.yaml).
repo-manager docs generate also creates a /lists directory containing flagged entities for repository management and continuous improvement, including:
/lists/logic-without-test-data.gen.md- Logic files lacking test data/lists/logic-test-results-missing.gen.md- Logic files with missing test results (typically indicating policy failures after runningrepo-manager policies test all)/lists/policy-with-todo.md.gen.md- Policies containing TODO files/lists/policy-without-description.md.gen- Policies missing description files/lists/policy-without-remediation.md.gen- Policies missing remediation guidance- And numerous other classifications
Key index files include:
/index.gen.md- Main repository index with links to all entities/frameworks/index.gen.md- Compliance framework directory/types/index.gen.md- CMDB type references/lists/index.gen.md- Management lists overview
All entities feature clickable links to related objects and associated lists. For example:
- Folders display contained policies
- Policies show linked framework sections
- Types list all logic files using them as
inputType
For active development sessions, use repo-manager docs generate --watch to enable real-time documentation updates when files change. (Warning: This feature remains in alpha)
Before pulling upstream changes, clean generated documentation with:
repo-manager docs cleanup
If you notice significant discrepancies between generated documentation and repository contents, use:
repo-manager docs cleanup
repo-manager policies test all
repo-manager docs generate
For CI/CD integration and static site generation, refer to Private repository documentation.
Environment Setup
For a detailed guide on setting up your local development environment, please see the Environment Setup documentation.
Policy Development
Executing and Debugging Policy
Any policy can be executed, and the results retrieved from your local IDE.
Prerequisites:
repo-managermust have an active authorization profile (seerepo-manager auth).- BigQuery Runner (or an alternative method for executing BigQuery queries) must be installed and configured (see VSCode Configuration).
- The policy's logic file you intend to execute must be syntactically correct.
To compile a policy into a query, execute the following command:
repo-manager policies generate DEBUG /ce/ca/aws/ec2/instance-detailed-monitoring/prod.logic.yaml
The output of this command should resemble the following:
profiles.json found in {pathToRepo}/.ca/profiles.json
Requested generation for *.logic.yaml: /ce/ca/aws/ec2/instance-detailed-monitoring/prod.logic.yaml
Generation bundle:
- /ce/ca/aws/ec2/instance-detailed-monitoring/policy.yaml
- /ce/ca/aws/ec2/instance-detailed-monitoring/prod.logic.yaml
- /types/CA10__CaAwsInstance__c/object.extracts.yaml
- /ce/ca/aws/ec2/instance-detailed-monitoring/test-data.json
Script written to '/ce/ca/aws/ec2/instance-detailed-monitoring/.generated/debug.sql'
This command informs you that the generated query is available in the file /ce/ca/aws/ec2/instance-detailed-monitoring/.generated/debug.sql. Navigate to this file.
The file contains a script with several queries:
- The main query, which produces raw results in a table named
ResultsDetailed. - Pre-generated debug queries for common debugging scenarios, such as:
- The number of objects triggering each specific condition.
- For fields used in each condition, the distinct values present in those fields. This is useful for determining values for fields representing different types, such as Instance Type, Database Engines, Encryption Types, etc.
- Other helpful queries, depending on the complexity of the logic.
These queries are intended as templates and examples for you to explore the data and understand how your policy functions with the available data. Feel free to modify the provided queries or create new ones. Ensure you save any queries you wish to keep outside the .generated directory, as this is a temporary directory that is deleted by repo-manager docs cleanup or by running repo-manager policies generate DEBUG.
The main query is useful for analyzing the general flow of the evaluation logic and provides the following columns:
scope- The scope of the conditions.0: {objectType}for the logic itself,1: {relationshipName}for the first related list, and so on.status- The status returned by the condition.conditionIndex- The index of the condition evaluated. Each condition group in the logic is assigned a block of 100 indexes. The condition from yourlogic.yamlfile will have an index ending in99. Indexes ending in01,02, etc., represent implicit conditions, such as checks for data availability or conditions that lead to anUNDETERMINEDstatus.conditionText- A human-readable representation of the condition logic.currentStateMessage- The message provided in the logic for this condition.runtimeError- A runtime error message, if one occurred; otherwise,null.objectCount- The number of objects for which this condition evaluated totrue.
Writing New Policy
Developing a policy involves defining its purpose, documenting its rationale, and creating the necessary files within the repository. Here's a breakdown of the process:
-
Define the Policy Idea: Clearly articulate the rule or idea you want to enforce or monitor in your cloud environment. Consider the business or security justification, potential impact of non-compliance, and whether it's technically feasible to implement.
-
Create Policy Folder: Follow the directory naming conventions to create a new directory under
/cefor your policy. For example, if you are creating a policy for AWS EC2 instances related to security, you might create a directory like/ce/my-company/aws/ec2/instance-security-baseline. Make sure all directories up to the policy directory havefolder.yamldescriptors. -
Create Policy Files:
policy.yaml: This is the core descriptor file. Define the policy'snames,description,type,categories,frameworkMappings,tags, and other relevant properties as described in thepolicy.yamlStructure section of this document.description.md: Write a detailed technical specification. Include sections for:- Rationale: Explain the business or security reasons behind the policy.
- Impact: Describe the potential risks and consequences of non-compliance.
- Audit: Outline manual procedures to verify compliance using the cloud console or CLI.
- References: Link to relevant external documentation, standards, or internal policies.
remediation.md: Provide clear and actionable steps for resolving non-compliant findings. Include:- Step-by-step remediation procedures.
- Console/CLI commands for remediation.
- Configuration best practices to prevent future violations.
- Optional Documentation: Consider creating
todo.mdfor implementation tasks andinternal.mdfor developer notes as needed.
-
Implement Logic:
- Create a logic file (e.g.,
prod.logic.yaml) to automate policy evaluation. Refer to the Logic section for the structure and properties of logic files. - Start with
wip.logic.yamlfor development and testing, and rename toprod.logic.yamlwhen the logic is production-ready. - Define
inputType,conditions,otherwise, andrelatedListsas needed to implement your policy logic. - Leverage Extracts to improve logic clarity and reusability.
- Create a logic file (e.g.,
-
Add Supporting Materials: Store any relevant screenshots, external documentation, API references, or internal notes within the policy directory to provide context and aid future maintenance.
-
Consider
impossiblePolicies: If a policy is valuable for documentation or research purposes but cannot be technically enforced due to API limitations, mark it withimpossible: trueinpolicy.yaml. This preserves valuable research and intent. -
Follow Naming Conventions: Strictly adhere to the Naming Conventions outlined in this document to ensure consistency and proper functioning of repository tools.
-
Test Your Logic Thoroughly: Use
repo-manager policies testand Test Data to validate your logic. -
Comment Your Policy Extensively: Add comments to
policy.yaml, logic files, and documentation. Explain the policy's purpose, implementation details, and any important considerations for future developers. Aim for a high comment-to-code ratio. Comments are invaluable for maintainability and understanding, especially for complex policies.