diff --git a/go.mod b/go.mod index ded7e31c..e466ef69 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/sergi/go-diff v1.3.1 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 + github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.31.0 k8s.io/apimachinery v0.31.0 @@ -22,6 +23,7 @@ require ( k8s.io/client-go v0.31.0 k8s.io/kubectl v0.31.0 sigs.k8s.io/e2e-framework v0.4.0 + sigs.k8s.io/kustomize/kyaml v0.17.1 sigs.k8s.io/yaml v1.4.0 ) @@ -114,6 +116,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.2 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect @@ -170,6 +173,5 @@ require ( sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.17.2 // indirect sigs.k8s.io/kustomize/kustomize/v5 v5.4.2 // indirect - sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/src/internal/inject/inject.go b/src/internal/inject/inject.go new file mode 100644 index 00000000..5d1db609 --- /dev/null +++ b/src/internal/inject/inject.go @@ -0,0 +1,109 @@ +package inject + +import ( + "fmt" + "strings" + + "sigs.k8s.io/kustomize/kyaml/yaml" +) + +// InjectMapData injects the subset map into a target map at the path +func InjectMapData(target, subset map[string]interface{}, path string) (map[string]interface{}, error) { + pathSlice := splitPath(path) + // Convert the target and subset maps to yaml nodes + targetNode, err := yaml.FromMap(target) + if err != nil { + return nil, fmt.Errorf("failed to create target node from map: %v", err) + } + + subsetNode, err := yaml.FromMap(subset) + if err != nil { + return nil, fmt.Errorf("failed to create subset node from map: %v", err) + } + + // Get the subset node from target + targetSubsetNode, err := targetNode.Pipe(yaml.LookupCreate(yaml.MappingNode, pathSlice...)) + if err != nil { + return nil, fmt.Errorf("error identifying subset node: %v", err) + } + + // Alternate merge based on custom merge function + err = mergeYAMLNodes(targetSubsetNode, subsetNode) + if err != nil { + return nil, fmt.Errorf("error merging subset into target: %v", err) + } + + if pathSlice[0] == "" { + targetNode = targetSubsetNode + } else { + if err := targetNode.PipeE(yaml.Lookup(pathSlice[:len(pathSlice)-1]...), yaml.SetField(pathSlice[len(pathSlice)-1], targetSubsetNode)); err != nil { + return nil, fmt.Errorf("error setting merged node back into target: %v", err) + } + } + + // Write targetNode into map[string]interface{} + targetMap, err := targetNode.Map() + if err != nil { + return nil, fmt.Errorf("failed to convert target node to map: %v", err) + } + + return targetMap, nil +} + +// splitPath splits a path by '.' into a path array +// TODO: This could be a more complicated path: is there a lib function to do this and possibly handle things like [] or escaped '.' +func splitPath(path string) []string { + // strip leading '.' if present + if len(path) > 0 && path[0] == '.' { + path = path[1:] + } + return strings.Split(path, ".") +} + +// mergeYAMLNodes recursively merges the subset node into the target node +// Note - this is an alternate to kyaml merge2 function which doesn't append lists, it replaces them +func mergeYAMLNodes(target, subset *yaml.RNode) error { + switch subset.YNode().Kind { + case yaml.MappingNode: + subsetFields, err := subset.Fields() + if err != nil { + return err + } + for _, field := range subsetFields { + subsetFieldNode, err := subset.Pipe(yaml.Lookup(field)) + if err != nil { + return err + } + targetFieldNode, err := target.Pipe(yaml.Lookup(field)) + if err != nil { + return err + } + + if targetFieldNode == nil { + // Field doesn't exist in target, so set it + err = target.PipeE(yaml.SetField(field, subsetFieldNode)) + if err != nil { + return err + } + } else { + // Field exists, merge it recursively + err = mergeYAMLNodes(targetFieldNode, subsetFieldNode) + if err != nil { + return err + } + } + } + case yaml.SequenceNode: + subsetItems, err := subset.Elements() + if err != nil { + return err + } + for _, item := range subsetItems { + target.YNode().Content = append(target.YNode().Content, item.YNode()) + } + default: + // Simple replacement for scalar and other nodes + target.YNode().Value = subset.YNode().Value + } + return nil +} diff --git a/src/internal/inject/inject_test.go b/src/internal/inject/inject_test.go new file mode 100644 index 00000000..776e3d65 --- /dev/null +++ b/src/internal/inject/inject_test.go @@ -0,0 +1,120 @@ +package inject_test + +import ( + "testing" + + "github.com/defenseunicorns/lula/src/internal/inject" + "github.com/stretchr/testify/assert" + goyaml "gopkg.in/yaml.v3" +) + +// TestInjectMapData tests the InjectMapData function +func TestInjectMapData(t *testing.T) { + tests := []struct { + name string + path string + target []byte + subset []byte + expected []byte + }{ + { + name: "test-merge-subset-with-list", + path: "metadata", + target: []byte(` +name: target +metadata: + some-data: target-data + only-target-field: data + some-submap: + only-target-field: target-data + sub-data: this-should-be-overwritten + some-list: + - item1 +`), + subset: []byte(` +some-data: subset-data +some-submap: + sub-data: my-submap-data + more-data: some-more-data +some-list: + - item2 + - item3 +`), + expected: []byte(` +name: target +metadata: + some-data: subset-data + only-target-field: data + some-submap: + only-target-field: target-data + sub-data: my-submap-data + more-data: some-more-data + some-list: + - item1 + - item2 + - item3 +`), + }, + { + name: "test-merge-at-root", + path: "", + target: []byte(` +name: target +some-information: some-data +some-map: + test-key: test-value +`), + subset: []byte(` +more-information: more-data +some-map: + test-key: subset-value +`), + expected: []byte(` +name: target +more-information: more-data +some-information: some-data +some-map: + test-key: subset-value +`), + }, + { + name: "test-merge-at-non-existant-path", + path: "metadata.test", + target: []byte(` +name: target +some-information: some-data +`), + subset: []byte(` +name: some-name +more-metdata: here +`), + expected: []byte(` +name: target +some-information: some-data +metadata: + test: + name: some-name + more-metdata: here +`), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := inject.InjectMapData(convertBytesToMap(t, tt.target), convertBytesToMap(t, tt.subset), tt.path) + if err != nil { + t.Errorf("InjectMapData() error = %v", err) + } + assert.Equal(t, result, convertBytesToMap(t, tt.expected), "The maps should be equal") + }) + } +} + +// convertBytesToMap converts a byte slice to a map[string]interface{} +func convertBytesToMap(t *testing.T, data []byte) map[string]interface{} { + var dataMap map[string]interface{} + if err := goyaml.Unmarshal(data, &dataMap); err != nil { + t.Errorf("yaml.Unmarshal failed: %v", err) + } + return dataMap +} diff --git a/src/pkg/common/oscal/complete-schema.go b/src/pkg/common/oscal/complete-schema.go index 35bc45b1..2fe5dbcd 100644 --- a/src/pkg/common/oscal/complete-schema.go +++ b/src/pkg/common/oscal/complete-schema.go @@ -9,6 +9,7 @@ import ( "github.com/defenseunicorns/go-oscal/src/pkg/files" oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2" + "github.com/defenseunicorns/lula/src/internal/inject" "github.com/defenseunicorns/lula/src/pkg/message" yamlV3 "gopkg.in/yaml.v3" "sigs.k8s.io/yaml" @@ -182,3 +183,63 @@ func GetOscalModel(model *oscalTypes_1_1_2.OscalModels) (modelType string, err e } } + +// InjectIntoOSCALModel takes a model target and a map[string]interface{} of values to inject into the model +func InjectIntoOSCALModel(target *oscalTypes_1_1_2.OscalModels, values map[string]interface{}, path string) (*oscalTypes_1_1_2.OscalModels, error) { + // If the target is nil, return an error + if target == nil { + return nil, fmt.Errorf("target model is nil") + } + + // Convert target to a map + modelMap, err := convertOscalModelToMap(*target) + if err != nil { + return nil, err + } + + // Inject the values into the map at the path + newModelMap, err := inject.InjectMapData(modelMap, values, path) + if err != nil { + return nil, err + } + + // Convert the new model map back to an OSCAL model + newModel, err := convertMapToOscalModel(newModelMap) + if err != nil { + return nil, err + } + + return newModel, nil +} + +// convertOscalModelToMap converts an OSCAL model to a map[string]interface{} +func convertOscalModelToMap(model oscalTypes_1_1_2.OscalModels) (map[string]interface{}, error) { + var modelMap map[string]interface{} + modelBytes, err := json.Marshal(model) + if err != nil { + return nil, err + } + + err = json.Unmarshal(modelBytes, &modelMap) + if err != nil { + return nil, err + } + + return modelMap, nil +} + +// convertMapToOscalModel converts a map[string]interface{} to an OSCAL model +func convertMapToOscalModel(modelMap map[string]interface{}) (*oscalTypes_1_1_2.OscalModels, error) { + var model oscalTypes_1_1_2.OscalModels + modelBytes, err := json.Marshal(modelMap) + if err != nil { + return nil, err + } + + err = json.Unmarshal(modelBytes, &model) + if err != nil { + return nil, err + } + + return &model, nil +} diff --git a/src/pkg/common/oscal/complete-schema_test.go b/src/pkg/common/oscal/complete-schema_test.go index 9b0ef282..d5577253 100644 --- a/src/pkg/common/oscal/complete-schema_test.go +++ b/src/pkg/common/oscal/complete-schema_test.go @@ -1,9 +1,12 @@ package oscal_test import ( + "testing" + oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2" "github.com/defenseunicorns/lula/src/pkg/common/oscal" - "testing" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" ) func TestGetOscalModel(t *testing.T) { @@ -68,5 +71,60 @@ func TestGetOscalModel(t *testing.T) { t.Fatalf("error GetOscalModel: expected: %s | got: %s", expected, actual) } } +} +func TestInjectIntoOSCALModel(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + path string + targetPath string + subsetPath string + expectedPath string + }{ + { + name: "inject-component-definition", + path: "component-definition.metadata", + targetPath: "../../../test/unit/common/oscal/valid-component.yaml", + subsetPath: "../../../test/unit/common/oscal/valid-component-metadata.yaml", + expectedPath: "../../../test/unit/common/oscal/valid-component-metadata-injected.yaml", + }, + { + name: "inject-ssp", + path: "system-security-plan.metadata", + targetPath: "../../../test/unit/common/oscal/valid-ssp.yaml", + subsetPath: "../../../test/unit/common/oscal/valid-ssp-metadata.yaml", + expectedPath: "../../../test/unit/common/oscal/valid-ssp-metadata-injected.yaml", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Convert paths to correct types + targetBytes := loadTestData(t, tt.targetPath) + subsetBytes := loadTestData(t, tt.subsetPath) + expectedBytes := loadTestData(t, tt.expectedPath) + + // Convert the test data to expected types + var targetModel oscalTypes_1_1_2.OscalCompleteSchema + if err := yaml.Unmarshal(targetBytes, &targetModel); err != nil { + t.Fatalf("yaml.Unmarshal failed: %v", err) + } + var subsetMap map[string]interface{} + if err := yaml.Unmarshal(subsetBytes, &subsetMap); err != nil { + t.Fatalf("yaml.Unmarshal failed: %v", err) + } + var expectedModel oscalTypes_1_1_2.OscalCompleteSchema + if err := yaml.Unmarshal(expectedBytes, &expectedModel); err != nil { + t.Fatalf("yaml.Unmarshal failed: %v", err) + } + + result, err := oscal.InjectIntoOSCALModel(&targetModel, subsetMap, tt.path) + if err != nil { + t.Errorf("InjectIntoOSCALModel() error = %v", err) + } + assert.Equal(t, *result, expectedModel, "The OSCAL models should be equal") + }) + } } diff --git a/src/test/unit/common/oscal/valid-component-metadata-injected.yaml b/src/test/unit/common/oscal/valid-component-metadata-injected.yaml new file mode 100644 index 00000000..4234649d --- /dev/null +++ b/src/test/unit/common/oscal/valid-component-metadata-injected.yaml @@ -0,0 +1,110 @@ +# add the descriptions inline +component-definition: + uuid: E6A291A4-2BC8-43A0-B4B2-FD67CAAE1F8F + metadata: + title: My OSCAL Injection Model + last-modified: "2022-09-13T12:00:00Z" + version: "20220913" + oscal-version: 1.1.2 + parties: + # Should be consistent across all of the packages, but where is ground truth? + - uuid: C18F4A9F-A402-415B-8D13-B51739D689FF + type: organization + name: Defense Unicorns + links: + - href: https://github.com/defenseunicorns/lula + rel: website + - uuid: e71d5dc5-3f5d-46ac-b6f1-f8ec41183d0f + type: organization + name: My Party + links: + - href: https://github.com/defenseunicorns/go-oscal + components: + - uuid: A9D5204C-7E5B-4C43-BD49-34DF759B9F04 + type: software + title: lula + description: | + Defense Unicorns lula + purpose: Validate compliance controls + responsible-roles: + - role-id: provider + party-uuids: + - C18F4A9F-A402-415B-8D13-B51739D689FF # matches parties entry for Defense Unicorns + control-implementations: + - uuid: A584FEDC-8CEA-4B0C-9F07-85C2C4AE751A + source: https://github.com/defenseunicorns/lula + description: Validate generic security requirements + implemented-requirements: + - uuid: 42C2FFDC-5F05-44DF-A67F-EEC8660AEFFD + control-id: ID-1 + description: >- + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum + dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + links: + - href: "#88AB3470-B96B-4D7C-BC36-02BF9563C46C" + rel: lula + back-matter: + resources: + - uuid: 88AB3470-B96B-4D7C-BC36-02BF9563C46C + remarks: >- + Get data for all resources fields specified + description: >- + metadata: + name: Validate pods with label foo=bar + uuid: 88AB3470-B96B-4D7C-BC36-02BF9563C46C + domain: + type: kubernetes + kubernetes-spec: + resources: + - name: jsoncm + resource-rule: + name: configmap-json + version: v1 + resource: configmaps + namespaces: [validation-test] + field: + jsonpath: .data.person.json + type: yaml + - name: yamlcm + resource-rule: + name: configmap-yaml + version: v1 + resource: configmaps + namespaces: [validation-test] + field: + jsonpath: .data.app-config.yaml + type: yaml + - name: secret + resource-rule: + name: example-secret + version: v1 + resource: secrets + namespaces: [validation-test] + field: + jsonpath: .data.auth + type: yaml + base64: true + - name: pod + resource-rule: + name: example-pod + version: v1 + resource: pods + namespaces: [validation-test] + field: + jsonpath: .metadata.annotations.annotation.io/simple + type: json + provider: + type: opa + opa-spec: + rego: | + package validate + + import future.keywords.every + + validate { + input.jsoncm.name == "bob" + input.yamlcm.logging.level == "INFO" + input.secret.username == "username" + "item1" in input.pod.items + } diff --git a/src/test/unit/common/oscal/valid-component-metadata.yaml b/src/test/unit/common/oscal/valid-component-metadata.yaml new file mode 100644 index 00000000..3d5875c7 --- /dev/null +++ b/src/test/unit/common/oscal/valid-component-metadata.yaml @@ -0,0 +1,8 @@ +title: My OSCAL Injection Model +oscal-version: 1.1.2 +parties: + - uuid: e71d5dc5-3f5d-46ac-b6f1-f8ec41183d0f + type: organization + name: My Party + links: + - href: https://github.com/defenseunicorns/go-oscal \ No newline at end of file diff --git a/src/test/unit/common/oscal/valid-ssp-metadata-injected.yaml b/src/test/unit/common/oscal/valid-ssp-metadata-injected.yaml new file mode 100644 index 00000000..e2a9b2de --- /dev/null +++ b/src/test/unit/common/oscal/valid-ssp-metadata-injected.yaml @@ -0,0 +1,318 @@ +system-security-plan: + uuid: cff8385f-108e-40a5-8f7a-82f3dc0eaba8 + metadata: + title: My New System Security Plan + last-modified: "2024-02-01T13:57:28.355446-04:00" + version: "1.2" + oscal-version: 1.1.2 + remarks: New metadata remarks added + roles: + - id: legal-officer + title: Legal Officer + - id: maintainer + title: System Maintainer + - id: asset-owner + title: System Assets Owner + - id: provider + title: System Provider + - id: asset-administrator + title: System Assets Admin + - id: legal-officer + title: Another Legal Officer + parties: + - uuid: 3b2a5599-cc37-403f-ae36-5708fa804b27 + type: organization + name: Enterprise Asset Owners + - uuid: 833ac398-5c9a-4e6b-acba-2a9c11399da0 + type: organization + name: Enterprise Asset Administrators + - uuid: ec485dcf-2519-43f5-8e7d-014cc315332d + type: organization + name: Legal Department + - uuid: 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + type: organization + name: IT Department + - uuid: 96c362ee-a012-4e07-92f3-486ab303b0e7 + type: organization + name: Acme Corp + import-profile: + href: '#b78aa3ec-915d-475b-8097-46813fae1825' + system-characteristics: + system-ids: + - identifier-type: https://ietf.org/rfc/rfc4122 + id: d7456980-9277-4dcb-83cf-f8ff0442623b + system-name: Enterprise Logging and Auditing System + description: This is an example of a system that provides enterprise logging and log auditing capabilities. + props: + - name: cloud-deployment-model + value: private-cloud + - name: cloud-service-model + value: iaas + security-sensitivity-level: moderate + system-information: + information-types: + - uuid: 7d28ac6e-5970-4f4c-a508-5a3715f0f02b + title: System and Network Monitoring + description: This system maintains historical logging and auditing information for all client devices connected to this system. + categorizations: + - system: https://doi.org/10.6028/NIST.SP.800-60v2r1 + information-type-ids: + - C.3.5.8 + confidentiality-impact: + base: fips-199-moderate + integrity-impact: + base: fips-199-moderate + availability-impact: + base: fips-199-low + security-impact-level: + security-objective-confidentiality: fips-199-moderate + security-objective-integrity: fips-199-moderate + security-objective-availability: fips-199-low + status: + state: other + remarks: This is an example, and is not intended to be implemented as a system + authorization-boundary: + description: The description of the authorization boundary would go here. + system-implementation: + users: + - uuid: 9824089b-322c-456f-86c4-4111c4200f69 + title: System Administrator + props: + - name: type + value: internal + role-ids: + - asset-administrator + - uuid: 9824089b-322c-456f-86c4-4111c4200f62 + title: System Maintainer + props: + - name: type + value: internal + role-ids: + - maintainer + - uuid: ae8de94c-835d-4303-83b1-114b6a117a07 + title: Audit Team + props: + - name: type + value: internal + role-ids: + - asset-owner + - uuid: 372ce7a3-92b0-437e-a98c-24d29f9bfab8 + title: Legal Department + props: + - name: type + value: internal + role-ids: + - legal-officer + - uuid: 372ce7a3-92b0-437e-a98c-55d29f9bfab8 + title: Provider + props: + - name: type + value: internal + role-ids: + - provider + components: + - uuid: 74042245-3db1-4f4d-be9a-ceb62d81152c + type: this-system + title: This System + description: The system described by this SSP. + status: + state: operational + - uuid: e00acdcf-911b-437d-a42f-b0b558cc4f03 + type: software + title: Logging Server + description: Provides a means for hosts to publish logged events to a central server. + status: + state: operational + responsible-roles: + - role-id: provider + party-uuids: + - 96c362ee-a012-4e07-92f3-486ab303b0e7 + - role-id: asset-owner + party-uuids: + - 3b2a5599-cc37-403f-ae36-5708fa804b27 + - role-id: asset-administrator + party-uuids: + - 833ac398-5c9a-4e6b-acba-2a9c11399da0 + - uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + type: policy + title: Enterprise Logging, Monitoring, and Alerting Policy + description: "Requires all components to send logs to the enterprise logging solution\n\n* Requires all components synchronize their time with the appropriate enterprise time service, and at what frequency. \n* Identifies the events that must be captured \n* Identifies who is responsible/accountable for performing these functions \n" + props: + - name: version + value: "2.1" + - name: release-date + value: "2018-10-15" + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - ec485dcf-2519-43f5-8e7d-014cc315332d + - uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + type: process + title: System Integration Process + description: Ensures proper integration into the enterprise as new systems are brought into production. + props: + - name: release-date + value: "2018-10-15" + links: + - href: '#795533ab-9427-4abe-820f-0b571bacfe6d' + rel: implements-policy + text: Ensures logs from components in new system are able to published to the logging server. Ensures log monitoring capabilities recognize new system as authorized. + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + - uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + type: process + title: Inventory Management Process + description: Describes how new components are introduced into the system - ensures monitoring teams know about every asset that should be producing logs, thus should be monitored. + props: + - name: release-date + value: "2018-10-15" + links: + - href: '#795533ab-9427-4abe-820f-0b571bacfe6d' + rel: implements-policy + text: Ensures that all host are known and authorized. Ensures that these hosts publish log events to the logging server. + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + - uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + type: guidance + title: Configuration Management Guidance + description: Describes how to configure a component to ensure its logs are transmitted to Splunk in the appropriate format. Also describes how to configure time synchronization. + props: + - name: release-date + value: "2018-10-15" + links: + - href: '#795533ab-9427-4abe-820f-0b571bacfe6d' + rel: implements-policy + text: Ensures that all host are configured to publish log events to the logging server. + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + inventory-items: + - uuid: c9c32657-a0eb-4cf2-b5c1-20928983063c + description: The logging server. + props: + - name: asset-id + value: asset-id-logging-server + responsible-parties: + - role-id: asset-administrator + party-uuids: + - 833ac398-5c9a-4e6b-acba-2a9c11399da0 + - role-id: asset-owner + party-uuids: + - 3b2a5599-cc37-403f-ae36-5708fa804b27 + implemented-components: + - component-uuid: e00acdcf-911b-437d-a42f-b0b558cc4f03 + props: + - name: asset-id + value: logging-server + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + props: + - name: asset-id + value: legal policy + remarks: This is a partial implementation that addresses the logging server portion of the auditing system. + control-implementation: + description: This is the control implementation for the system. + implemented-requirements: + - uuid: aaadb3ff-6ae8-4332-92db-211468c52af2 + control-id: au-1 + statements: + - statement-id: au-1_smt + uuid: 7ad47329-dc55-4196-a19d-178a8fe7438d + - statement-id: au-1_smt.a + uuid: f3887a91-9ed3-425c-b305-21e4634a1c34 + by-components: + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + uuid: a74681b2-fbcb-46eb-90fd-0d55aa74ac7b + description: The legal department develops, documents and disseminates this policy to all staff and contractors within the organization. + set-parameters: + - param-id: au-1_prm_1 + values: + - all staff and contractors within the organization + - component-uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + uuid: 4f873ce6-dd49-4a46-bd4a-5041c22665f1 + description: The IT department created and maintains this procedure. This department disseminates it to all IT staff who administer this system when the staff member is assigned and annually through training. + set-parameters: + - param-id: au-1_prm_1 + values: + - all IT staff who administer this system when the staff member is assigned and annually through training + - component-uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + uuid: ea85a624-cd21-4c63-abe0-f66087e97241 + description: The IT department created and maintains this procedure. This department disseminates it to all IT staff who administer this system when the staff member is assigned and annually through training. + set-parameters: + - param-id: au-1_prm_1 + values: + - all IT staff who administer this system when the staff member is assigned and annually through training + - component-uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + uuid: b5e5823a-844f-4306-a5ab-7e110679e0d5 + description: The IT department created and maintains this procedure. This department disseminates it to all IT staff who administer this system when the staff member is assigned and annually through training. + set-parameters: + - param-id: au-1_prm_1 + values: + - all IT staff who administer this system when the staff member is assigned and annually through training + - statement-id: au-1_smt.a.1 + uuid: 6fe632bd-33aa-4eea-a507-a37f0d212085 + by-components: + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + uuid: 2d0a7b08-da7f-4691-b99c-8fd9df02b25c + description: This policy explicitly states the purpose and scope of the policy in Section 1. Roles and responsibilities are described in Section 2. This section also describes responsibilities for organizational coordination. Management commitment and compliance statements are made in the board’s directive memo dated January 1, 2012. + - statement-id: au-1_smt.a.2 + uuid: dbe9af68-1cd9-4ff1-965b-8f887351d411 + by-components: + - component-uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + uuid: dd4fd380-7a2a-4fba-9e98-933ba5cfc04d + description: 'This process aligns with the enterprise Logging, Monitoring, and Alerting Policy, Version 2.1, October 15, 2018. The following processes work together to fully implement the policy: System Integration Process, Inventory Management Process, Configuration Management, Log Review Process, and Monitoring and Alerting Process' + - component-uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + uuid: 3b912d0f-2463-497c-8d8a-72416f38e999 + description: 'This process aligns with the enterprise Logging, Monitoring, and Alerting Policy, Version 2.1, October 15, 2018. The following processes work together to fully implement the policy: System Integration Process, Inventory Management Process, Configuration Management, Log Review Process, and Monitoring and Alerting Process' + - component-uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + uuid: 226ee2a2-cbdb-498f-8182-94dfa013476c + description: 'This process aligns with the enterprise Logging, Monitoring, and Alerting Policy, Version 2.1, October 15, 2018. The following processes work together to fully implement the policy: System Integration Process, Inventory Management Process, Configuration Management, Log Review Process, and Monitoring and Alerting Process' + - statement-id: au-1_smt.b + uuid: b1773cd6-afc5-4c87-84a7-f182e6be5af9 + remarks: N/A + - statement-id: au-1_smt.b.1 + uuid: 75873308-f37d-4e89-9c27-29f3dee4b314 + by-components: + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + uuid: 23903c59-1327-46f0-9c28-09ec7f144214 + description: The legal department reviews this policy annually, and other times as necessary in response to regulatory or organizational changes. The legal department updates the policy as needed based on these reviews. + set-parameters: + - param-id: au-1_prm_2 + values: + - annually, and other times as necessary in response to regulatory or organizational changes + - statement-id: au-1_smt.b.2 + uuid: 74b5b0f2-9915-4f80-b7cd-379566442ab6 + by-components: + - component-uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + uuid: 0c45b6e2-f85b-4656-a6cc-2a302d184720 + description: The IT department reviews this process annually, and other times as necessary in response to regulatory or organizational changes. The IT department updates the policy as needed based on these reviews. + set-parameters: + - param-id: au-1_prm_3 + values: + - annually, and other times as necessary in response to regulatory or organizational changes + - component-uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + uuid: 094f02ce-4b7a-405c-90a5-ab4d95133f74 + description: The IT department reviews this process annually, and other times as necessary in response to regulatory or organizational changes. The IT department updates the policy as needed based on these reviews. + set-parameters: + - param-id: au-1_prm_3 + values: + - annually, and other times as necessary in response to regulatory or organizational changes + - component-uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + uuid: 7ec8b7ec-d931-4055-ac74-6d288d636787 + description: The IT department reviews this process annually, and other times as necessary in response to regulatory or organizational changes. The IT department updates the policy as needed based on these reviews + set-parameters: + - param-id: au-1_prm_3 + values: + - annually, and other times as necessary in response to regulatory or organizational changes \ No newline at end of file diff --git a/src/test/unit/common/oscal/valid-ssp-metadata.yaml b/src/test/unit/common/oscal/valid-ssp-metadata.yaml new file mode 100644 index 00000000..baa472c4 --- /dev/null +++ b/src/test/unit/common/oscal/valid-ssp-metadata.yaml @@ -0,0 +1,6 @@ +title: My New System Security Plan +version: "1.2" +roles: + - id: legal-officer + title: Another Legal Officer +remarks: New metadata remarks added \ No newline at end of file diff --git a/src/test/unit/common/oscal/valid-ssp.yaml b/src/test/unit/common/oscal/valid-ssp.yaml new file mode 100644 index 00000000..bf2e31f6 --- /dev/null +++ b/src/test/unit/common/oscal/valid-ssp.yaml @@ -0,0 +1,315 @@ +system-security-plan: + uuid: cff8385f-108e-40a5-8f7a-82f3dc0eaba8 + metadata: + title: Enterprise Logging and Auditing System Security Plan + last-modified: "2024-02-01T13:57:28.355446-04:00" + version: "1.1" + oscal-version: 1.1.2 + roles: + - id: legal-officer + title: Legal Officer + - id: maintainer + title: System Maintainer + - id: asset-owner + title: System Assets Owner + - id: provider + title: System Provider + - id: asset-administrator + title: System Assets Admin + parties: + - uuid: 3b2a5599-cc37-403f-ae36-5708fa804b27 + type: organization + name: Enterprise Asset Owners + - uuid: 833ac398-5c9a-4e6b-acba-2a9c11399da0 + type: organization + name: Enterprise Asset Administrators + - uuid: ec485dcf-2519-43f5-8e7d-014cc315332d + type: organization + name: Legal Department + - uuid: 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + type: organization + name: IT Department + - uuid: 96c362ee-a012-4e07-92f3-486ab303b0e7 + type: organization + name: Acme Corp + import-profile: + href: '#b78aa3ec-915d-475b-8097-46813fae1825' + system-characteristics: + system-ids: + - identifier-type: https://ietf.org/rfc/rfc4122 + id: d7456980-9277-4dcb-83cf-f8ff0442623b + system-name: Enterprise Logging and Auditing System + description: This is an example of a system that provides enterprise logging and log auditing capabilities. + props: + - name: cloud-deployment-model + value: private-cloud + - name: cloud-service-model + value: iaas + security-sensitivity-level: moderate + system-information: + information-types: + - uuid: 7d28ac6e-5970-4f4c-a508-5a3715f0f02b + title: System and Network Monitoring + description: This system maintains historical logging and auditing information for all client devices connected to this system. + categorizations: + - system: https://doi.org/10.6028/NIST.SP.800-60v2r1 + information-type-ids: + - C.3.5.8 + confidentiality-impact: + base: fips-199-moderate + integrity-impact: + base: fips-199-moderate + availability-impact: + base: fips-199-low + security-impact-level: + security-objective-confidentiality: fips-199-moderate + security-objective-integrity: fips-199-moderate + security-objective-availability: fips-199-low + status: + state: other + remarks: This is an example, and is not intended to be implemented as a system + authorization-boundary: + description: The description of the authorization boundary would go here. + system-implementation: + users: + - uuid: 9824089b-322c-456f-86c4-4111c4200f69 + title: System Administrator + props: + - name: type + value: internal + role-ids: + - asset-administrator + - uuid: 9824089b-322c-456f-86c4-4111c4200f62 + title: System Maintainer + props: + - name: type + value: internal + role-ids: + - maintainer + - uuid: ae8de94c-835d-4303-83b1-114b6a117a07 + title: Audit Team + props: + - name: type + value: internal + role-ids: + - asset-owner + - uuid: 372ce7a3-92b0-437e-a98c-24d29f9bfab8 + title: Legal Department + props: + - name: type + value: internal + role-ids: + - legal-officer + - uuid: 372ce7a3-92b0-437e-a98c-55d29f9bfab8 + title: Provider + props: + - name: type + value: internal + role-ids: + - provider + components: + - uuid: 74042245-3db1-4f4d-be9a-ceb62d81152c + type: this-system + title: This System + description: The system described by this SSP. + status: + state: operational + - uuid: e00acdcf-911b-437d-a42f-b0b558cc4f03 + type: software + title: Logging Server + description: Provides a means for hosts to publish logged events to a central server. + status: + state: operational + responsible-roles: + - role-id: provider + party-uuids: + - 96c362ee-a012-4e07-92f3-486ab303b0e7 + - role-id: asset-owner + party-uuids: + - 3b2a5599-cc37-403f-ae36-5708fa804b27 + - role-id: asset-administrator + party-uuids: + - 833ac398-5c9a-4e6b-acba-2a9c11399da0 + - uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + type: policy + title: Enterprise Logging, Monitoring, and Alerting Policy + description: "Requires all components to send logs to the enterprise logging solution\n\n* Requires all components synchronize their time with the appropriate enterprise time service, and at what frequency. \n* Identifies the events that must be captured \n* Identifies who is responsible/accountable for performing these functions \n" + props: + - name: version + value: "2.1" + - name: release-date + value: "2018-10-15" + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - ec485dcf-2519-43f5-8e7d-014cc315332d + - uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + type: process + title: System Integration Process + description: Ensures proper integration into the enterprise as new systems are brought into production. + props: + - name: release-date + value: "2018-10-15" + links: + - href: '#795533ab-9427-4abe-820f-0b571bacfe6d' + rel: implements-policy + text: Ensures logs from components in new system are able to published to the logging server. Ensures log monitoring capabilities recognize new system as authorized. + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + - uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + type: process + title: Inventory Management Process + description: Describes how new components are introduced into the system - ensures monitoring teams know about every asset that should be producing logs, thus should be monitored. + props: + - name: release-date + value: "2018-10-15" + links: + - href: '#795533ab-9427-4abe-820f-0b571bacfe6d' + rel: implements-policy + text: Ensures that all host are known and authorized. Ensures that these hosts publish log events to the logging server. + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + - uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + type: guidance + title: Configuration Management Guidance + description: Describes how to configure a component to ensure its logs are transmitted to Splunk in the appropriate format. Also describes how to configure time synchronization. + props: + - name: release-date + value: "2018-10-15" + links: + - href: '#795533ab-9427-4abe-820f-0b571bacfe6d' + rel: implements-policy + text: Ensures that all host are configured to publish log events to the logging server. + status: + state: operational + responsible-roles: + - role-id: maintainer + party-uuids: + - 0f0c15ed-565e-4ce9-8670-b54853d0bf03 + inventory-items: + - uuid: c9c32657-a0eb-4cf2-b5c1-20928983063c + description: The logging server. + props: + - name: asset-id + value: asset-id-logging-server + responsible-parties: + - role-id: asset-administrator + party-uuids: + - 833ac398-5c9a-4e6b-acba-2a9c11399da0 + - role-id: asset-owner + party-uuids: + - 3b2a5599-cc37-403f-ae36-5708fa804b27 + implemented-components: + - component-uuid: e00acdcf-911b-437d-a42f-b0b558cc4f03 + props: + - name: asset-id + value: logging-server + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + props: + - name: asset-id + value: legal policy + remarks: This is a partial implementation that addresses the logging server portion of the auditing system. + control-implementation: + description: This is the control implementation for the system. + implemented-requirements: + - uuid: aaadb3ff-6ae8-4332-92db-211468c52af2 + control-id: au-1 + statements: + - statement-id: au-1_smt + uuid: 7ad47329-dc55-4196-a19d-178a8fe7438d + - statement-id: au-1_smt.a + uuid: f3887a91-9ed3-425c-b305-21e4634a1c34 + by-components: + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + uuid: a74681b2-fbcb-46eb-90fd-0d55aa74ac7b + description: The legal department develops, documents and disseminates this policy to all staff and contractors within the organization. + set-parameters: + - param-id: au-1_prm_1 + values: + - all staff and contractors within the organization + - component-uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + uuid: 4f873ce6-dd49-4a46-bd4a-5041c22665f1 + description: The IT department created and maintains this procedure. This department disseminates it to all IT staff who administer this system when the staff member is assigned and annually through training. + set-parameters: + - param-id: au-1_prm_1 + values: + - all IT staff who administer this system when the staff member is assigned and annually through training + - component-uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + uuid: ea85a624-cd21-4c63-abe0-f66087e97241 + description: The IT department created and maintains this procedure. This department disseminates it to all IT staff who administer this system when the staff member is assigned and annually through training. + set-parameters: + - param-id: au-1_prm_1 + values: + - all IT staff who administer this system when the staff member is assigned and annually through training + - component-uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + uuid: b5e5823a-844f-4306-a5ab-7e110679e0d5 + description: The IT department created and maintains this procedure. This department disseminates it to all IT staff who administer this system when the staff member is assigned and annually through training. + set-parameters: + - param-id: au-1_prm_1 + values: + - all IT staff who administer this system when the staff member is assigned and annually through training + - statement-id: au-1_smt.a.1 + uuid: 6fe632bd-33aa-4eea-a507-a37f0d212085 + by-components: + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + uuid: 2d0a7b08-da7f-4691-b99c-8fd9df02b25c + description: This policy explicitly states the purpose and scope of the policy in Section 1. Roles and responsibilities are described in Section 2. This section also describes responsibilities for organizational coordination. Management commitment and compliance statements are made in the board’s directive memo dated January 1, 2012. + - statement-id: au-1_smt.a.2 + uuid: dbe9af68-1cd9-4ff1-965b-8f887351d411 + by-components: + - component-uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + uuid: dd4fd380-7a2a-4fba-9e98-933ba5cfc04d + description: 'This process aligns with the enterprise Logging, Monitoring, and Alerting Policy, Version 2.1, October 15, 2018. The following processes work together to fully implement the policy: System Integration Process, Inventory Management Process, Configuration Management, Log Review Process, and Monitoring and Alerting Process' + - component-uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + uuid: 3b912d0f-2463-497c-8d8a-72416f38e999 + description: 'This process aligns with the enterprise Logging, Monitoring, and Alerting Policy, Version 2.1, October 15, 2018. The following processes work together to fully implement the policy: System Integration Process, Inventory Management Process, Configuration Management, Log Review Process, and Monitoring and Alerting Process' + - component-uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + uuid: 226ee2a2-cbdb-498f-8182-94dfa013476c + description: 'This process aligns with the enterprise Logging, Monitoring, and Alerting Policy, Version 2.1, October 15, 2018. The following processes work together to fully implement the policy: System Integration Process, Inventory Management Process, Configuration Management, Log Review Process, and Monitoring and Alerting Process' + - statement-id: au-1_smt.b + uuid: b1773cd6-afc5-4c87-84a7-f182e6be5af9 + remarks: N/A + - statement-id: au-1_smt.b.1 + uuid: 75873308-f37d-4e89-9c27-29f3dee4b314 + by-components: + - component-uuid: 795533ab-9427-4abe-820f-0b571bacfe6d + uuid: 23903c59-1327-46f0-9c28-09ec7f144214 + description: The legal department reviews this policy annually, and other times as necessary in response to regulatory or organizational changes. The legal department updates the policy as needed based on these reviews. + set-parameters: + - param-id: au-1_prm_2 + values: + - annually, and other times as necessary in response to regulatory or organizational changes + - statement-id: au-1_smt.b.2 + uuid: 74b5b0f2-9915-4f80-b7cd-379566442ab6 + by-components: + - component-uuid: 941e2a87-46f4-4b3e-9e87-bbd187091ca1 + uuid: 0c45b6e2-f85b-4656-a6cc-2a302d184720 + description: The IT department reviews this process annually, and other times as necessary in response to regulatory or organizational changes. The IT department updates the policy as needed based on these reviews. + set-parameters: + - param-id: au-1_prm_3 + values: + - annually, and other times as necessary in response to regulatory or organizational changes + - component-uuid: fa39eb84-3014-46b4-b6bc-7da10527c262 + uuid: 094f02ce-4b7a-405c-90a5-ab4d95133f74 + description: The IT department reviews this process annually, and other times as necessary in response to regulatory or organizational changes. The IT department updates the policy as needed based on these reviews. + set-parameters: + - param-id: au-1_prm_3 + values: + - annually, and other times as necessary in response to regulatory or organizational changes + - component-uuid: 4938767c-dd8b-4ea4-b74a-fafffd48ac99 + uuid: 7ec8b7ec-d931-4055-ac74-6d288d636787 + description: The IT department reviews this process annually, and other times as necessary in response to regulatory or organizational changes. The IT department updates the policy as needed based on these reviews + set-parameters: + - param-id: au-1_prm_3 + values: + - annually, and other times as necessary in response to regulatory or organizational changes \ No newline at end of file