Skip to content

Conversation

@jpower432
Copy link
Contributor

@jpower432 jpower432 commented Aug 8, 2025

What Changed?

  • AssessmentMethod was added
  • The cue schema for layer4 was updated to validate the updated structure generate using the library

⚠️ BREAKING
This removes the AssessmentStep type. Similar functionality can be acheived with the MethodExecutor on AssessmentMethod.

Note: Adapted from work on AssessmentMethods done by @trumant in #19

Rationale

Adding AssessmentMethod supports a multi-method Assessment that is flexible enough to accommodate different types of procedures to complete a control requirement. This new structure also captures detailed information about each individual check. The goal of AssessmentMethod is to be self-contained, allowing for composability and ensuring the solution retains the core functionality and structure of AssessmentSteps.

Open Questions

EDITED: Added questions from initial feedback

  • Is Assessment Method the most clear terminology to use? Perhaps Assessment Procedure?
  • If we want Assessment Methods to be seen as only as "options" do they need individual pre-condition steps?

Testing

A new file under layer4/testdata was added that is populated output from a Layer 4 structure generated by the TestEvaluate unit test. This was used to validate against the updated in the cue schema.

cue vet -d "#Layer4" schemas/layer-4.cue layer4/testdata/good-evaluation.yml

Issues

Closes #73
Overlaps/Impact #23

@jpower432 jpower432 requested a review from a team as a code owner August 8, 2025 22:32
Copy link
Contributor

@trumant trumant left a comment

Choose a reason for hiding this comment

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

Quick review from my phone. Will take a deeper look on Monday morning

"corrupted-state": bool
// RemediationGuide is the URL to the documentation for this evaluation
"remediation-guide": string
// Assessments is a map of pointers to Assessment objects to establish idempotency
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks to be a slice not a map

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Found that in a couple places actually. Updated on the last commit.

// Methods is a slice of assessment methods that were executed during the test
methods: [...#AssessmentMethod]
// MethodsExecuted is the number of assessment methods that were executed during the test
"methods-executed"?: int @go(MethodExecuted)
Copy link
Contributor

Choose a reason for hiding this comment

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

Singular/plural mismatch

"target-object"?: _
}
// TargetName is the name or ID of the resource or configuration that is to be changed
"target-name": string @go(TagertName)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"target-name": string @go(TagertName)
"target-name": string @go(TargetName)

@jpower432 jpower432 requested a review from trumant August 12, 2025 15:58
// Methods defines the assessment methods associated with the assessment
methods: [...#AssessmentMethod]
// MethodsExecuted is the number of assessment methods that were executed during the assessment
"methods-executed"?: int @go(MethodsExecuted)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this data summarized here when it can be computed easily enough by the data consumer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the feedback. You're right - the steps-counter field made sense for a standalone function, but with the new run field in the AssessmentMethod struct, it's redundant.

@jpower432 jpower432 marked this pull request as draft August 14, 2025 13:07
@jpower432 jpower432 force-pushed the break/assessment-method branch from 04bf5a4 to fc8a208 Compare August 19, 2025 16:34
jpower432 and others added 10 commits August 19, 2025 12:37
Moves from AssessmentStep to AssessmentMethod to allow
for metadata to be used to describe the check or test

Signed-off-by: Jennifer Power <[email protected]>
The layer 4 schema is not up to date with the Go code
implemented. This chanes updates the schema and uses evaluation
data generated from L4 unit tests to verify againt the schema.

Signed-off-by: Jennifer Power <[email protected]>
Some of the comments around AssessementMethod require clarification
around intended usage

Signed-off-by: Jennifer Power <[email protected]>
To better show the impact of the change, the testdata was
updated to an example from the pvtr baseline validator

Signed-off-by: Jennifer Power <[email protected]>
This commit refactors the AssessmentMethod schema to use
CUE's disjunction feature to formally define conditional
logic for the run and result fields. The schema was allowing
a state where run was true but a result was missing.

Signed-off-by: Jennifer Power <[email protected]>
Co-authored-by: Travis Truman <[email protected]>
Signed-off-by: Jennifer Power <[email protected]>
Signed-off-by: Jennifer Power <[email protected]>
This change normalizes descriptions between different
types defined in cue for layer4 and removes Go type
language from the cue schema comments

Signed-off-by: Jennifer Power <[email protected]>
@jpower432 jpower432 force-pushed the break/assessment-method branch from fc8a208 to d51aed2 Compare August 19, 2025 16:38
This change refactors the work in the previous commits to allow for
top-level metadata to support different types of assessment procedures
and move the AssessmentSteps under AssessmentProcedure struct. The concept of
"method" is updated to describe the procedure categorically for tools that run
automated procedures.

Signed-off-by: Jennifer Power <[email protected]>
@jpower432 jpower432 force-pushed the break/assessment-method branch from d51aed2 to d431b80 Compare August 19, 2025 21:11
@jpower432
Copy link
Contributor Author

Add a commment to describe the refactor in d431b80

What Changed?

  • AssessmentProcedure was added
  • AssessmentStep functionality is kept as is and moved under the Assessment Procedure

Rationale

Results from a maintainer discussion where we decided the assessment logic should keep steps as they currently are, but adding procedure to allow for each assessment to contain multiple groups of steps.

Points of Discussion

  • The concept of ProcedureMethod was added here to ensure the automated control evaluation skipped over any assessment procedures that should be completed by a human. I initially added the Test method and the Observation method to describe how the results of the procedure are to be determined.

  • The Assessment does not halt other procedures if a procedure fails. However, the procedure will halt if a step fails.

Open Questions

  • Message handling - If mulitple procedures run, how should should the Assessment message aggregate them?

"documentation-url"?: =~"^https?://[^\\s]+$"
"corrupted-state"?: bool
"assessment-results"?: [...#AssessmentResult]
// Name is the name of the control being evaluated
Copy link
Contributor

Choose a reason for hiding this comment

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

If we expect a tool will consume lower layers and produce output conforming with ControlEvaluation, should we consider a datetime here or elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree a timestamp would be valuable. The run-duration field in Assessments is useful, but I'm wondering if it would make more sense to include a start and end datetime and let the consumer calculate the duration as needed. WDYT?

Comment on lines +39 to +40
// RunDuration is the time it took to run the assessment
"run-duration"?: string @go(RunDuration)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do the typical data consumers care how long the assessment took? Or, put another way, what value does this data provide and to whome?

Copy link
Contributor Author

@jpower432 jpower432 Aug 22, 2025

Choose a reason for hiding this comment

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

Agree. This was part of the attempt to align the schema with the current struct in the Go library. I would propose start and end timestamps instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I proposed something to address the run-duration field here - #112

// RunDuration is the time it took to run the assessment
"run-duration"?: string @go(RunDuration)
// Value is the object that was returned during the assessment
value?: _
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

this one's a bit legacy — was used to log details about the inspected value

Comment on lines +33 to +34
// Result communicates whether the assessment has been run, and if so, the outcome(s)
result: #Result
Copy link
Contributor

Choose a reason for hiding this comment

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

The "has been run" language here confuses me.

In what circumstances or use cases do we expect to have a document conforming to this schema that does not represent an Assessment activity that occurred in the past?

Is there value in having a layer4 payload that communicates an "intended" or "future" assessment?

Copy link
Contributor Author

@jpower432 jpower432 Aug 22, 2025

Choose a reason for hiding this comment

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

I think there are two use cases I was trying to capture:

  1. Currently, steps can have the state of NotRun if a prior Assessment Step has failed and the process is halted.
  2. Part of my intent/goal with adding the Procedures was to allow Layer4 to be used in pre-run state (essentially like a test plan) as an input to a tool to execute the tests and fill in the result information.

// Result communicates whether the assessment has been run, and if so, the outcome(s)
result: #Result
// Message describes the result of the assessment
message: string
Copy link
Contributor

Choose a reason for hiding this comment

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

If it's describing the result, can we put it in #Result?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I proposed something here to update the existing Result field - #113

Comment on lines +86 to +87
// ProcedureMethod describes method options that can be used to determine the results
#ProcedureMethod: "Test" | "Observation"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to clarify the language here. In my experience testing involves observation.

What value does this provide to the intended data consumers? How do you see them using this fact?

Copy link
Contributor Author

@jpower432 jpower432 Aug 22, 2025

Choose a reason for hiding this comment

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

I agree, these could be more descriptive. I wanted to allow categorization of the prodecures based on if the results were determined with automation or human judgement of behavior or state.

Perhaps:

Suggested change
// ProcedureMethod describes method options that can be used to determine the results
#ProcedureMethod: "Test" | "Observation"
#EvaluationMethod: "Automated" | "Manual"

How this would be used might depend on if we want to support Layer4 as an input. This allows categorization of the procedures so that they might be handled differently to determine the results.

Comment on lines +63 to +64
// Steps provides the address for the assessment steps executed
"steps"?: [...string]
Copy link
Contributor

Choose a reason for hiding this comment

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

How is a consumer of this data going to interpret, analyze or otherwise make use of this particular field?

Comment on lines +81 to +84
#Result: #ResultWhenRun | "Not Run"

// Result describes the outcome(s) of an assessment procedure when it is executed.
#ResultWhenRun: "Passed" | "Failed" | "Needs Review" | "Not Applicable" | "Unknown"
Copy link
Contributor

Choose a reason for hiding this comment

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

Contingent on the decision above on "has been run", but I'd propose removing #ResultWhenRun altogether

Copy link
Contributor Author

@jpower432 jpower432 Aug 22, 2025

Choose a reason for hiding this comment

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

I'm thinking a potential solution here is to capture whether a step, assessment, or procedure ran in different field like run and keep the results field focused on assessment outcomes. Perhaps this would align with your comment about adding message to results. WDYT?

@jpower432
Copy link
Contributor Author

Looks like this branch has drifted from main. I will perform a rebase and get it back into a reviewable state.

@jpower432
Copy link
Contributor Author

Superseded by #117

@jpower432 jpower432 closed this Sep 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support mapping declarative policy identifiers or locations to layer4.Assessments as steps

3 participants