Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Examples of Component Definitions with Rules #94

Closed
wants to merge 11 commits into from

Conversation

aj-stein-nist
Copy link
Contributor

@aj-stein-nist aj-stein-nist commented Feb 3, 2022

Committer Notes

These are examples of component-definitions that make us of the rule construct under evaluation in usnistgov/OSCAL#1058.

NOTE: These are labelled WIP (Work In Progress) and are subject to change. Please report feedback on the issue, but also check for updates to the shape of the code as it changes.

All Submissions:

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • Have you squashed any non-relevant commits and commit messages? [instructions]
  • Do all automated CI/CD checks pass?

Changes to Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you included examples of how to use your new feature(s)?

"uuid": "a969feae-ae93-422f-8a95-9362adef826b",
"title": "Check hardening guidelines for OCP kubelet instances with OpenSCAP",
"condition": "kubelet is hardened with CIS OCPv4 baseline validated with OpenSCAP",
"condition-tests": [

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure of the purpose of condition (it is just text)? What does condition test and steps represent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now? Just text. At this stage in OSCAL, it will be a short summary statement in the first version. In a later revision and with certain OSCAL internals adapted or enhanced, we can have a structured condition, just not at this time.

"value": "5%",
"class": "argument"
}
],
Copy link

@vikas-agarwal76 vikas-agarwal76 Feb 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems specific rules in OCP4 CIS -

1.3.1 Ensure that garbage collection is configured as appropriate

- kubelet_eviction_thresholds_set_soft_memory_available
- kubelet_eviction_thresholds_set_soft_nodefs_available
- kubelet_eviction_thresholds_set_soft_nodefs_inodesfree
- kubelet_eviction_thresholds_set_soft_imagefs_available

are captured as steps here. This is not the intended use. Each rule under 1.3.1 above should be represented as a separate rule in OSCAL and not as step. Each of these rule can be associated with control/statement under "implemented-requirements" and evaluated separately.

Also, there should be a way to specify parameters for a rule. Same or similar construct used in catalogs for specifying parameters can be used here (inside a rule).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are captured as steps here. This is not the intended use. Each rule under 1.3.1 above should be represented as a separate rule in OSCAL and not as step.

I had alluded to this when we met, but I think you could reasonably expect to do both. I guess I would need to find a way to explain this and show it in examples. Given a condition you want to test or verify from a CIS OpenSCAP baseline (or as they call it, a profile, different from an OSCAL profile, I know) do you want to all 100 tests in one rule or do? Do you want to have 100 rules separately?

In short you might have reasons for doing both.

Each of these rule can be associated with control/statement under "implemented-requirements" and evaluated separately.

I thought we support this now, maybe the examples aren't clear. That's on me!

This can be done bidirectionally, but the feedback given in a prior meeting was the linkage would go from a statement in an implemented-requirement. In the example look for the prop with @name="evidence" in the examples and you will see a UUID reference pointing to the rule, or individual steps.

Also, there should be a way to specify parameters for a rule. Same or similar construct used in catalogs for specifying parameters can be used here (inside a rule).

This will have to come after we handle parameters in a deeper way, in a later version of OSCAL. We have not forgotten!

@ancatri
Copy link

ancatri commented Feb 14, 2022

Hi AJ,

The rules & parameters & tests go hand in hand in compliance. Thus, the rules concept and the parameters concept and the tests concept should follow a parallel exposure and treatment in the OSCAL schemas.
Like in catalog: there are generic params declared for all the controls, and then there are specific params declared at control level
Like in profile: the list of controls comes together with the list of parameters.
This mind set will help place the rules and params appropriately in the component definition schema and the SSP schema.

SSP it is straight forward:
To validate a component, we need the set of tests and the set of expected parameter values associated with that component for a given regulation (control implementation, eg NIST, HIPPA).
The assumption here is that the rules, params, tests have been declared in Component Definition.

control-implementation [1]: {
      description [1]: markup-multiline,
      **set-parameters** [0 or 1]: [ … ], -> list of the params expected on the systems
      **select-tests** [0 or 1] : […] -> list of the checks expected to test the systems
      implemented-requirements [1]: [ … ], [
      An array of implemented-requirement objects [1 to ∞] {
              uuid [1]: uuid,
              control-id [1]: token,
              description [1]: markup-multiline,
              props [0 or 1]: [ … ],
              links [0 or 1]: [ … ],
              **set-parameters** [0 or 1]: [ … ],
              **select-tests** [0 or 1] : […],
              responsible-roles [0 or 1]: [ … ],
              statements [0 or 1]: [ … ],
              remarks [0 or 1]: markup-multiline

Let now look at the Component Definition. I first show the schema and then I give an example for ROKS OpenShift as component_type "service", associated with OSCO, Tanium and OpesSCAP as component_type "validation".

Schema:

component-definition [1]: {
        uuid [1]: uuid,
        components [0 or 1]: [
        An array of component objects [1 to ∞] {
                    uuid [1]: uuid,
                    type [1]: string,
                    title [1]: markup-line,
                    description [1]: markup-multiline,
                    purpose [0 or 1]: markup-line,
                    props [0 or 1]: [ … ],
                    links [0 or 1]: [ … ],
                    responsible-roles [0 or 1]: [ … ],
                    protocols [0 or 1]: [ … ],
                    **rules** [0 or 1]: […] -> component rules 
                    **parameters** [0 or 1]: [ … ], -> component params with valid values 
                    **tests** [0 or 1]: […] -> component checks associated with rules&params
                    control-implementations [0 or 1]: [ … [
                    An array of control-implementation objects [1 to ∞] {
                          uuid [1]: uuid,
                          source [1]: uri-reference,
                          description [1]: markup-multiline,
                          props [0 or 1]: [ … ],
                          links [0 or 1]: [ … ],
                          **rules** [0 or 1]: […] -> component rules specific for this regulation controls
                          **select-tests** [0 or 1]: [ … ], -> rules checks recommended across this regulation controls
                          **set-parameters** [0 or 1]: [ … ], -> params values recommended across this regulation controls
                          implemented-requirements [1]: [
                          An array of implemented-requirement objects [1 to ∞] {
                                        uuid [1]: uuid,
                                        control-id [1]: token,
                                        description [1]: markup-,
                                        props [0 or 1]: [ … ],
                                        links [0 or 1]: [ … ],
                                        **rules** [0 or 1]: […] -> component rules specific for this control
                                        **select-tests** : […] -> rules checks recommended for this control
                                        **set-parameters** [0 or 1]: [ … ], -> params values recommended for this control
                                        responsible-roles [0 or 1]: [ … ],
                                        statements [0 or 1]: [ … ],
                                                  **rules** [0 or 1]: […] -> component rules specific for this statement 
                                                  **select-tests** [0 or 1] : […] -> rules checks recommended for this statement
                                                  **set-parameters** [0 or 1]: [ … ], -> params values recommended for this statement
                                        remarks [0 or 1]: markup-multiline

Example for ROKS OpenShift as component_type "service":

component-definition [1]: {
        uuid [1]: uuid,
        components [0 or 1]: [ {
                  uuid [1]: uuid,
                  type [1]: Service,
                  title [1]: ROKS OpenShift,
                  description [1]: markup-multiline,
                  purpose [0 or 1]: markup-line,
                  props [0 or 1]: [ … ],
                  links [0 or 1]: [ … ],
                  responsible-roles [0 or 1]: [ … ],
                  protocols [0 or 1]: [ … ],
                  _**rules** [0 or 1]:  […] ->    kubelet_eviction_thresholds_set_hard_imagefs_available
                  **parameters** [0 or 1]: [ … ], ->  var_kubelet_evictionhard_imagefs_available
                                                                      5%, 10%, 15%, 20%
                  **tests** [0 or 1]: […] ->_ 
                  control-implementations [0 or 1]: [ … [
                          An array of control-implementation objects [1 to ∞] {
                          uuid [1]: uuid,
                          source [1]: uri-reference for OCP4 CIS benchmark catalog OR NIST 800-53 v5 catalog OR PCI Catalog
                          description [1]: markup-multiline,
                          props [0 or 1]: [ … ],
                          links [0 or 1]: [ … ],
                          _**rules** [0 or 1]:  […] ->    kubelet_eviction_thresholds_set_hard_imagefs_available
                          **set-parameters** [0 or 1]: [ … ] -> var_kubelet_evictionhard_imagefs_available
                                                                                10%
                          **select-tests** [0 or 1]: […] ->_    
                          implemented-requirements [1]: [
                                          An array of implemented-requirement objects [1 to ∞] {
                                          uuid [1]: uuid,
                                          control-id [1]: "cm-6.1",
                                          description [1]: "CM-6(1)",
                                          props [0 or 1]: [ … ],
                                          links [0 or 1]: [ … ],
                                          **rules** [0 or 1]:  […] ->    kubelet_eviction_thresholds_set_hard_imagefs_available
                                          **set-parameters** [0 or 1]: [ … ] -> var_kubelet_evictionhard_imagefs_available
                                                                                                10%
                                          **select-tests** [0 or 1]: […] ->   
                                          responsible-roles [0 or 1]: [ … ],
                                          statements [0 or 1]: [ … ],
                                                  _**rules** [0 or 1]:  […] ->    kubelet_eviction_thresholds_set_hard_imagefs_available
                                                  **set-parameters** [0 or 1]: [ … ] -> var_kubelet_evictionhard_imagefs_available
                                                                                                        10%
                                                  **select-tests** [0 or 1]: […] ->_   
                                          remarks [0 or 1]: markup-multiline

Example for OSCO, Tanium and OpesSCAP as component_type "validation":

component-definition [1]: {
      uuid [1]: uuid,
      components [0 or 1]: [ {
                uuid [1]: uuid,
                type [1]: Validation,
                title [1]: OSCO / OpenSCAP / Tanium
                description [1]: markup-multiline,
                purpose [0 or 1]: markup-line,
                props [0 or 1]: [ … ],
                links [0 or 1]: [ … ],
                responsible-roles [0 or 1]: [ … ],
                protocols [0 or 1]: [ … ],
                **rules** [0 or 1]: […] ->
                **parameters** [0 or 1]: [ … ], -> my_var_kubelet_evictionhard_imagefs__available
                                                                    5%, 10%, 15%, 20%
                **tests** : […] ->     
                xccdf_org.ssgproject.content_rule_kubelet_eviction_thresholds_set_hard_imagefs_available
                           props 
                                 component : "ROKS"
                                 rule : "kubelet_eviction_thresholds_set_hard_imagefs_available"
                                 param : "var_kubelet_evictionhard_imagefs__available"
                                (here is an example where the props grouping support would be needed)
                                

@aj-stein-nist
Copy link
Contributor Author

OK, @ancatri, I know we have discussed this before, but for this current iteration, I want to leave out parameters to make the discussion.

  1. Can you clarify for us what do you mean with the rules and checks split out as different items at the same level in the hierarchy?

(As it stands now a rule ~ check as we have discussed them (we discuss that is conceptually the same thing), unless we mean the check as the result of processing a rule elsewhere (which is what usnistgov/OSCAL#1059 is about.)

  1. What is the objective of set-checks versus set-parameters? Leaving parameters, can you explain how that would work separately, with mechanics, that is different from conceptually what a parameter is?

Thanks for your comments! I would look forward to discussing them soon enough.

@ancatri
Copy link

ancatri commented Feb 15, 2022

Rule is NOT a check...

Rule is an English statement, it is the policy: "Ensure Software_a had config_b set to c." This takes param "config_b"
Check is the code (python, javascript, rego) that tests the rule, policy above is valid. This takes param "my_config_b".

We have for a given Rule in a product many ways to test , many checks.

@aj-stein-nist
Copy link
Contributor Author

OK, time to update these with the redesigned model pushed up in usnistgov/OSCAL@f3e2e01.

@aj-stein-nist
Copy link
Contributor Author

There have been some significant changes and I will be re-opening a new draft PR to address better exhaustive examples of the rules for usnistgov/OSCAL#1364. I will not delete the branch from my work however, if people wish to review in the interim.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants