diff --git a/policy/governance/governance.rego b/policy/governance/governance.rego index b255e78..4942a64 100644 --- a/policy/governance/governance.rego +++ b/policy/governance/governance.rego @@ -1,27 +1,38 @@ package governance + import data.security default allow = false -pullrequest_attestations := - [att | json.unmarshal(input[i].Attestation).predicateType == "https://liatr.io/attestations/github-pull-request/v1"; att := json.unmarshal(input[i].Attestation)] +pullrequest_attestations := [att | json.unmarshal(input[i].Attestation).predicateType == "https://liatr.io/attestations/github-pull-request/v1"; att := json.unmarshal(input[i].Attestation)] -trivy_attestations := - [att | json.unmarshal(input[i].Attestation).predicateType == "https://cosign.sigstore.dev/attestation/vuln/v1"; att := json.unmarshal(input[i].Attestation)] +trivy_attestations := [att | json.unmarshal(input[i].Attestation).predicateType == "https://cosign.sigstore.dev/attestation/vuln/v1"; att := json.unmarshal(input[i].Attestation)] -sbom_attestations := - [att | json.unmarshal(input[i].Attestation).predicateType == "https://spdx.dev/Document"; att := json.unmarshal(input[i].Attestation)] +sbom_attestations := [att | json.unmarshal(input[i].Attestation).predicateType == "https://spdx.dev/Document"; att := json.unmarshal(input[i].Attestation)] +provenance_attestations := [att | json.unmarshal(input[i].Attestation).predicateType == "https://slsa.dev/provenance/v0.2"; att := json.unmarshal(input[i].Attestation)] allow { - violations := pullrequest_violations | trivy_violations | sbom_violations - print(violations) - count(violations) == 0 + violations := ((pullrequest_violations | trivy_violations) | sbom_violations) | provenance_violations + print(violations) + count(violations) == 0 +} + +provenance_violations[msg] { + count(provenance_attestations) == 0 + msg := "no provenance attestation" +} + +provenance_violations[msg] { + some i + attestation := provenance_attestations[i] + not security.provenance.allow with input as attestation + msg := "provenance violation found" } pullrequest_violations[msg] { - count(pullrequest_attestations) == 0 - msg := "no pull request attestation" + count(pullrequest_attestations) == 0 + msg := "no pull request attestation" } pullrequest_violations[msg] { @@ -30,13 +41,13 @@ pullrequest_violations[msg] { } sbom_violations[msg] { - count(sbom_attestations) == 0 - msg:= "no sbom attestation" + count(sbom_attestations) == 0 + msg := "no sbom attestation" } trivy_violations[msg] { - count(trivy_attestations) == 0 - msg := "no trivy attestation" + count(trivy_attestations) == 0 + msg := "no trivy attestation" } trivy_violations[msg] { diff --git a/policy/governance/governance_test.rego b/policy/governance/governance_test.rego index 5aa24c4..48bda56 100644 --- a/policy/governance/governance_test.rego +++ b/policy/governance/governance_test.rego @@ -3,13 +3,13 @@ package governance_test import data.governance.allow test_all_pass { - case := [data.test.pullrequest.two_reviewers, data.test.trivy.no_results, data.test.sbom.app] + case := [data.test.pullrequest.two_reviewers, data.test.trivy.no_results, data.test.sbom.app, data.test.provenance] allow with input as case } test_fail_no_pull_request { - case := [data.test.trivy.no_results] - not allow with input as case + case := [data.test.trivy.no_results] + not allow with input as case } test_fail_no_reviewer { @@ -28,6 +28,6 @@ test_fail_medium_vuln { } test_fail_no_sbom { - case := [data.test.pullrequest.two_reviewers, data.test.trivy.no_results] - not allow with input as case -} \ No newline at end of file + case := [data.test.pullrequest.two_reviewers, data.test.trivy.no_results] + not allow with input as case +} diff --git a/policy/governance/identities.rego b/policy/governance/identities.rego index 43365ff..e874d19 100644 --- a/policy/governance/identities.rego +++ b/policy/governance/identities.rego @@ -1,12 +1,12 @@ package governance signer_identities := [ - { - "issuer": "https://token.actions.githubusercontent.com", - "subjectRegExp": `^https://github\.com/liatrio/gh-trusted-builds-workflows/\.github/workflows/build-and-push\.yaml@refs/tags/v\d+\.\d+\.\d+$`, - }, - { - "issuer": "https://token.actions.githubusercontent.com", - "subjectRegExp": `^https://github\.com/liatrio/gh-trusted-builds-workflows/\.github/workflows/scan-image\.yaml@refs/tags/v\d+\.\d+\.\d+$`, - } + { + "issuer": "https://token.actions.githubusercontent.com", + "subjectRegExp": `^https://github\.com/liatrio/gh-trusted-builds-workflows/\.github/workflows/build-and-push\.yaml@refs/tags/v\d+\.\d+\.\d+$`, + }, + { + "issuer": "https://token.actions.githubusercontent.com", + "subjectRegExp": `^https://github\.com/liatrio/gh-trusted-builds-workflows/\.github/workflows/scan-image\.yaml@refs/tags/v\d+\.\d+\.\d+$`, + }, ] diff --git a/policy/security/provenance.rego b/policy/security/provenance.rego new file mode 100644 index 0000000..e653520 --- /dev/null +++ b/policy/security/provenance.rego @@ -0,0 +1,21 @@ +package security.provenance + +default allow = false + +allow { + count(violation) == 0 +} + +buildType := "https://github.com/slsa-framework/slsa-github-generator/container@v1" + +orgName := "Liatrio" + +violation[msg] { + input.predicate.buildType != buildType + msg := "provenance build type is incorrect" +} + +violation[msg] { + input.predicate.invocation.environment.github_event_payload.enterprise.name != orgName + msg := "provenance enterprise name is not Liatrio" +} diff --git a/policy/security/provenance_test.rego b/policy/security/provenance_test.rego new file mode 100644 index 0000000..8954dad --- /dev/null +++ b/policy/security/provenance_test.rego @@ -0,0 +1,33 @@ +package security.provenance + +# Test that allow is false when buildType is incorrect +test_fail_incorrect_buildType { + input := {"predicate": {"buildType": "incorrect_buildType", "invocation": {"environment": {"github_event_payload": {"enterprise": {"name": "Liatrio"}}}}}} + not allow with input as input +} + +# Test that allow is false when enterprise name is not Liatrio +test_fail_incorrect_enterprise_name { + input := {"predicate": {"buildType": "https://github.com/slsa-framework/slsa-github-generator/container@v1", "invocation": {"environment": {"github_event_payload": {"enterprise": {"name": "NotLiatrio"}}}}}} + not allow with input as input +} + +# Test that allow is true when buildType is correct and enterprise name is Liatrio +test_allow_correct_buildType_and_enterprise_name { + input := {"predicate": {"buildType": "https://github.com/slsa-framework/slsa-github-generator/container@v1", "invocation": {"environment": {"github_event_payload": {"enterprise": {"name": "Liatrio"}}}}}} + allow with input as input +} + +# Test that violation message is correct when buildType is incorrect +test_violation_incorrect_buildType { + input := {"predicate": {"buildType": "incorrect_buildType", "invocation": {"environment": {"github_event_payload": {"enterprise": {"name": "Liatrio"}}}}}} + violation[msg] with input as input + msg == "provenance build type is incorrect" +} + +# Test that violation message is correct when enterprise name is not Liatrio +test_violation_incorrect_enterprise_name { + input := {"predicate": {"buildType": "https://github.com/slsa-framework/slsa-github-generator/container@v1", "invocation": {"environment": {"github_event_payload": {"enterprise": {"name": "NotLiatrio"}}}}}} + violation[msg] with input as input + msg == "provenance enterprise name is not Liatrio" +} diff --git a/policy/security/pullrequest_test.rego b/policy/security/pullrequest_test.rego new file mode 100644 index 0000000..05f7027 --- /dev/null +++ b/policy/security/pullrequest_test.rego @@ -0,0 +1,33 @@ +package security.pullrequest + +# Test that allow is false when there are no reviewers +test_allow_no_reviewers { + input := {"predicate": {"reviewers": null}} + not allow with input as input +} + +# Test that allow is false when reviewers count is less than 1 +test_allow_less_than_one_reviewer { + input := {"predicate": {"reviewers": []}} + not allow with input as input +} + +# Test that allow is true when reviewers count is 1 or more +test_allow_one_or_more_reviewers { + input := {"predicate": {"reviewers": ["Alice"]}} + allow with input as input +} + +# Test that violation message is correct when there are no reviewers +test_violation_no_reviewers { + input := {"predicate": {"reviewers": null}} + violation[msg] with input as input + msg == "pull request reviewers is null" +} + +# Test that violation message is correct when reviewers count is less than 1 +test_violation_less_than_one_reviewer { + input := {"predicate": {"reviewers": []}} + violation[msg] with input as input + msg == "pull request reviewers is less than 1" +} diff --git a/policy/security/trivy.rego b/policy/security/trivy.rego index 3e09573..dc7ee6b 100644 --- a/policy/security/trivy.rego +++ b/policy/security/trivy.rego @@ -3,11 +3,11 @@ package security.trivy default allow = false allow { - count(violation) == 0 + count(violation) == 0 } violation[msg] { - severities := ["MEDIUM","HIGH","CRITICAL"] - input.predicate.scanner.result.Results[_].Vulnerabilities[_].Severity == severities[_] - msg := "vulnerability higher than medium" -} \ No newline at end of file + severities := ["MEDIUM", "HIGH", "CRITICAL"] + input.predicate.scanner.result.Results[_].Vulnerabilities[_].Severity == severities[_] + msg := "vulnerability higher than medium" +} diff --git a/test/provenance.json b/test/provenance.json new file mode 100644 index 0000000..9d58988 --- /dev/null +++ b/test/provenance.json @@ -0,0 +1,25 @@ +{ + "provenance": { + "Attestation": "{\"_type\":\"https://in-toto.io/Statement/v0.1\",\"predicateType\":\"https://slsa.dev/provenance/v0.2\",\"subject\":[{\"name\":\"ghcr.io/liatrio/gh-trusted-builds-app\",\"digest\":{\"sha256\":\"39ada25f4ddc545afdc5f577bcd65a665a50e72ea572dad4ac79e63664470c47\"}}],\"predicate\":{\"builder\":{\"id\":\"https://github.com/liatrio/gh-trusted-builds-workflows/.github/workflows/build-and-push.yaml@refs/tags/v2.0.13\"},\"buildType\":\"https://github.com/slsa-framework/slsa-github-generator/container@v1\",\"invocation\":{\"configSource\":{\"uri\":\"git+https://github.com/liatrio/gh-trusted-builds-app@refs/heads/main\",\"digest\":{\"sha1\":\"fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\"},\"entryPoint\":\".github/workflows/app.yaml\"},\"parameters\":{},\"environment\":{\"github_actor\":\"alexashley\",\"github_actor_id\":\"9082799\",\"github_base_ref\":\"\",\"github_event_name\":\"push\",\"github_event_payload\":{\"after\":\"fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\",\"base_ref\":null,\"before\":\"8355442c7a097cbdeb5f19358737f5ff610a5824\",\"commits\":[{\"author\":{\"email\":\"alexashley@users.noreply.github.com\",\"name\":\"AlexAshley\",\"username\":\"alexashley\"},\"committer\":{\"email\":\"noreply@github.com\",\"name\":\"GitHub\",\"username\":\"web-flow\"},\"distinct\":true,\"id\":\"fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\",\"message\":\"feat:approvedchange(#55)\",\"timestamp\":\"2024-03-15T15:34:58-04:00\",\"tree_id\":\"735c09ddac812ab94144e5d919e7df3bab00034e\",\"url\":\"https://github.com/liatrio/gh-trusted-builds-app/commit/fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\"}],\"compare\":\"https://github.com/liatrio/gh-trusted-builds-app/compare/8355442c7a09...fe9fc7ffa58e\",\"created\":false,\"deleted\":false,\"enterprise\":{\"avatar_url\":\"https://avatars.githubusercontent.com/b/9988?v=4\",\"created_at\":\"2021-11-02T23:03:56Z\",\"description\":\"\",\"html_url\":\"https://github.com/enterprises/liatrio-partnerdemo\",\"id\":9988,\"name\":\"Liatrio\",\"node_id\":\"E_kgDNJwQ\",\"slug\":\"liatrio-partnerdemo\",\"updated_at\":\"2023-09-19T00:04:56Z\",\"website_url\":\"\"},\"forced\":false,\"head_commit\":{\"author\":{\"email\":\"alexashley@users.noreply.github.com\",\"name\":\"AlexAshley\",\"username\":\"alexashley\"},\"committer\":{\"email\":\"noreply@github.com\",\"name\":\"GitHub\",\"username\":\"web-flow\"},\"distinct\":true,\"id\":\"fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\",\"message\":\"feat:approvedchange(#55)\",\"timestamp\":\"2024-03-15T15:34:58-04:00\",\"tree_id\":\"735c09ddac812ab94144e5d919e7df3bab00034e\",\"url\":\"https://github.com/liatrio/gh-trusted-builds-app/commit/fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\"},\"organization\":{\"avatar_url\":\"https://avatars.githubusercontent.com/u/5726618?v=4\",\"description\":\"EnterpriseDeliveryTransformation,DevOps,CloudNativeAutomation\",\"events_url\":\"https://api.github.com/orgs/liatrio/events\",\"hooks_url\":\"https://api.github.com/orgs/liatrio/hooks\",\"id\":5726618,\"issues_url\":\"https://api.github.com/orgs/liatrio/issues\",\"login\":\"liatrio\",\"members_url\":\"https://api.github.com/orgs/liatrio/members{/member}\",\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjU3MjY2MTg=\",\"public_members_url\":\"https://api.github.com/orgs/liatrio/public_members{/member}\",\"repos_url\":\"https://api.github.com/orgs/liatrio/repos\",\"url\":\"https://api.github.com/orgs/liatrio\"},\"pusher\":{\"email\":\"alexashley@users.noreply.github.com\",\"name\":\"alexashley\"},\"ref\":\"refs/heads/main\",\"repository\":{\"allow_forking\":true,\"archive_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/{archive_format}{/ref}\",\"archived\":false,\"assignees_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/assignees{/user}\",\"blobs_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/git/blobs{/sha}\",\"branches_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/branches{/branch}\",\"clone_url\":\"https://github.com/liatrio/gh-trusted-builds-app.git\",\"collaborators_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/collaborators{/collaborator}\",\"comments_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/comments{/number}\",\"commits_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/commits{/sha}\",\"compare_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/compare/{base}...{head}\",\"contents_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/contents/{+path}\",\"contributors_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/contributors\",\"created_at\":1684768749,\"custom_properties\":{},\"default_branch\":\"main\",\"deployments_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/deployments\",\"description\":null,\"disabled\":false,\"downloads_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/downloads\",\"events_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/events\",\"fork\":false,\"forks\":0,\"forks_count\":0,\"forks_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/forks\",\"full_name\":\"liatrio/gh-trusted-builds-app\",\"git_commits_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/git/commits{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/git/refs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/git/tags{/sha}\",\"git_url\":\"git://github.com/liatrio/gh-trusted-builds-app.git\",\"has_discussions\":false,\"has_downloads\":true,\"has_issues\":true,\"has_pages\":false,\"has_projects\":true,\"has_wiki\":true,\"homepage\":\"\",\"hooks_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/hooks\",\"html_url\":\"https://github.com/liatrio/gh-trusted-builds-app\",\"id\":643991426,\"is_template\":false,\"issue_comment_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/issues/comments{/number}\",\"issue_events_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/issues/events{/number}\",\"issues_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/issues{/number}\",\"keys_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/keys{/key_id}\",\"labels_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/labels{/name}\",\"language\":\"Mermaid\",\"languages_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/languages\",\"license\":null,\"master_branch\":\"main\",\"merges_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/merges\",\"milestones_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/milestones{/number}\",\"mirror_url\":null,\"name\":\"gh-trusted-builds-app\",\"node_id\":\"R_kgDOJmKHgg\",\"notifications_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/notifications{?since,all,participating}\",\"open_issues\":1,\"open_issues_count\":1,\"organization\":\"liatrio\",\"owner\":{\"avatar_url\":\"https://avatars.githubusercontent.com/u/5726618?v=4\",\"email\":\"cloudservices@liatrio.com\",\"events_url\":\"https://api.github.com/users/liatrio/events{/privacy}\",\"followers_url\":\"https://api.github.com/users/liatrio/followers\",\"following_url\":\"https://api.github.com/users/liatrio/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/liatrio/gists{/gist_id}\",\"gravatar_id\":\"\",\"html_url\":\"https://github.com/liatrio\",\"id\":5726618,\"login\":\"liatrio\",\"name\":\"liatrio\",\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjU3MjY2MTg=\",\"organizations_url\":\"https://api.github.com/users/liatrio/orgs\",\"received_events_url\":\"https://api.github.com/users/liatrio/received_events\",\"repos_url\":\"https://api.github.com/users/liatrio/repos\",\"site_admin\":false,\"starred_url\":\"https://api.github.com/users/liatrio/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/liatrio/subscriptions\",\"type\":\"Organization\",\"url\":\"https://api.github.com/users/liatrio\"},\"private\":false,\"pulls_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/pulls{/number}\",\"pushed_at\":1710531298,\"releases_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/releases{/id}\",\"size\":117,\"ssh_url\":\"git@github.com:liatrio/gh-trusted-builds-app.git\",\"stargazers\":20,\"stargazers_count\":20,\"stargazers_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/stargazers\",\"statuses_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/statuses/{sha}\",\"subscribers_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/subscribers\",\"subscription_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/subscription\",\"svn_url\":\"https://github.com/liatrio/gh-trusted-builds-app\",\"tags_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/tags\",\"teams_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/teams\",\"topics\":[\"automated-governance\",\"noarchive\"],\"trees_url\":\"https://api.github.com/repos/liatrio/gh-trusted-builds-app/git/trees{/sha}\",\"updated_at\":\"2023-08-21T17:50:36Z\",\"url\":\"https://github.com/liatrio/gh-trusted-builds-app\",\"visibility\":\"public\",\"watchers\":20,\"watchers_count\":20,\"web_commit_signoff_required\":false},\"sender\":{\"avatar_url\":\"https://avatars.githubusercontent.com/u/9082799?v=4\",\"events_url\":\"https://api.github.com/users/alexashley/events{/privacy}\",\"followers_url\":\"https://api.github.com/users/alexashley/followers\",\"following_url\":\"https://api.github.com/users/alexashley/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/alexashley/gists{/gist_id}\",\"gravatar_id\":\"\",\"html_url\":\"https://github.com/alexashley\",\"id\":9082799,\"login\":\"alexashley\",\"node_id\":\"MDQ6VXNlcjkwODI3OTk=\",\"organizations_url\":\"https://api.github.com/users/alexashley/orgs\",\"received_events_url\":\"https://api.github.com/users/alexashley/received_events\",\"repos_url\":\"https://api.github.com/users/alexashley/repos\",\"site_admin\":false,\"starred_url\":\"https://api.github.com/users/alexashley/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/alexashley/subscriptions\",\"type\":\"User\",\"url\":\"https://api.github.com/users/alexashley\"}},\"github_head_ref\":\"\",\"github_ref\":\"refs/heads/main\",\"github_ref_type\":\"branch\",\"github_repository_id\":\"643991426\",\"github_repository_owner\":\"liatrio\",\"github_repository_owner_id\":\"5726618\",\"github_run_attempt\":\"1\",\"github_run_id\":\"8301443632\",\"github_run_number\":\"150\",\"github_sha1\":\"fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\"}},\"metadata\":{\"buildInvocationID\":\"8301443632-1\",\"completeness\":{\"parameters\":true,\"environment\":false,\"materials\":false},\"reproducible\":false},\"materials\":[{\"uri\":\"git+https://github.com/liatrio/gh-trusted-builds-app@refs/heads/main\",\"digest\":{\"sha1\":\"fe9fc7ffa58e26987b13040ffac4609ed5cabf9f\"}}]}}", + "AttestationType": "", + "Body": { + "IntotoObj": { + "content": { + "hash": { + "algorithm": "sha256", + "value": "bf66066855f676c74df977444f48366a07469ecf6fcd7e336c01e43f90f90355" + }, + "payloadHash": { + "algorithm": "sha256", + "value": "123faf5cffc92437bc9d26a4a905dda0dea272b179c1fc523d9a088b2c148aa3" + } + }, + "publicKey": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUcvakNDQm9XZ0F3SUJBZ0lVUXpoekpHTTlzVVU4NXpLalVhcWpTa1dHN1NRd0NnWUlLb1pJemowRUF3TXcKTnpFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUjR3SEFZRFZRUURFeFZ6YVdkemRHOXlaUzFwYm5SbApjbTFsWkdsaGRHVXdIaGNOTWpNd05USTJNVFkwTVRFd1doY05Nak13TlRJMk1UWTFNVEV3V2pBQU1Ga3dFd1lICktvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVvTU5TbFNUVFZKT1FDeVYvWVJPQlhJK1QzdW54L2YwOGFmQkQKMFFCRjhOZzk0SnpKK3ZDNGJRQndwNTZVQjRtQi9kNlV4U1duc2xOSVZmNXNEeU4xWktPQ0JhUXdnZ1dnTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREF6QWRCZ05WSFE0RUZnUVVTQTBFCkx3NEdIV1I0UGJkZlNFMkJaWlVMVmhZd0h3WURWUjBqQkJnd0ZvQVUzOVBwejFZa0VaYjVxTmpwS0ZXaXhpNFkKWkQ4d2VnWURWUjBSQVFIL0JIQXdib1pzYUhSMGNITTZMeTluYVhSb2RXSXVZMjl0TDJ4cFlYUnlhVzh2WjJndApkSEoxYzNSbFpDMWlkV2xzWkhNdGQyOXlhMlpzYjNkekx5NW5hWFJvZFdJdmQyOXlhMlpzYjNkekwySjFhV3hrCkxXRnVaQzF3ZFhOb0xubGhiV3hBY21WbWN5OW9aV0ZrY3k5elltOXRNRGtHQ2lzR0FRUUJnNzh3QVFFRUsyaDAKZEhCek9pOHZkRzlyWlc0dVlXTjBhVzl1Y3k1bmFYUm9kV0oxYzJWeVkyOXVkR1Z1ZEM1amIyMHdId1lLS3dZQgpCQUdEdnpBQkFnUVJkMjl5YTJac2IzZGZaR2x6Y0dGMFkyZ3dOZ1lLS3dZQkJBR0R2ekFCQXdRb01qSm1OMll4Ck9EZ3pORFkzTVRVMU5HWTJaak0zWVRsak1HWXhaRFpqTUdJeFpqSTBNakZtTkRBUkJnb3JCZ0VFQVlPL01BRUUKQkFOaGNIQXdLd1lLS3dZQkJBR0R2ekFCQlFRZGJHbGhkSEpwYnk5bmFDMTBjblZ6ZEdWa0xXSjFhV3hrY3kxaApjSEF3SFFZS0t3WUJCQUdEdnpBQkJnUVBjbVZtY3k5b1pXRmtjeTl6WW05dE1Ec0dDaXNHQVFRQmc3OHdBUWdFCkxRd3JhSFIwY0hNNkx5OTBiMnRsYmk1aFkzUnBiMjV6TG1kcGRHaDFZblZ6WlhKamIyNTBaVzUwTG1OdmJUQjgKQmdvckJnRUVBWU8vTUFFSkJHNE1iR2gwZEhCek9pOHZaMmwwYUhWaUxtTnZiUzlzYVdGMGNtbHZMMmRvTFhSeQpkWE4wWldRdFluVnBiR1J6TFhkdmNtdG1iRzkzY3k4dVoybDBhSFZpTDNkdmNtdG1iRzkzY3k5aWRXbHNaQzFoCmJtUXRjSFZ6YUM1NVlXMXNRSEpsWm5NdmFHVmhaSE12YzJKdmJUQTRCZ29yQmdFRUFZTy9NQUVLQkNvTUtEZGgKWWpCbVlXSXlPRFptWVRSbE1HWTNOalZrWlRRNE0yUTROVGd4Tm1OallqWmhNalJrTVRnd0hRWUtLd1lCQkFHRAp2ekFCQ3dRUERBMW5hWFJvZFdJdGFHOXpkR1ZrTUVBR0Npc0dBUVFCZzc4d0FRd0VNZ3d3YUhSMGNITTZMeTluCmFYUm9kV0l1WTI5dEwyeHBZWFJ5YVc4dloyZ3RkSEoxYzNSbFpDMWlkV2xzWkhNdFlYQndNRGdHQ2lzR0FRUUIKZzc4d0FRMEVLZ3dvTWpKbU4yWXhPRGd6TkRZM01UVTFOR1kyWmpNM1lUbGpNR1l4WkRaak1HSXhaakkwTWpGbQpOREFmQmdvckJnRUVBWU8vTUFFT0JCRU1EM0psWm5NdmFHVmhaSE12YzJKdmJUQVpCZ29yQmdFRUFZTy9NQUVQCkJBc01DVFkwTXprNU1UUXlOakFxQmdvckJnRUVBWU8vTUFFUUJCd01HbWgwZEhCek9pOHZaMmwwYUhWaUxtTnYKYlM5c2FXRjBjbWx2TUJjR0Npc0dBUVFCZzc4d0FSRUVDUXdITlRjeU5qWXhPREJyQmdvckJnRUVBWU8vTUFFUwpCRjBNVzJoMGRIQnpPaTh2WjJsMGFIVmlMbU52YlM5c2FXRjBjbWx2TDJkb0xYUnlkWE4wWldRdFluVnBiR1J6CkxXRndjQzh1WjJsMGFIVmlMM2R2Y210bWJHOTNjeTloY0hBdWVXRnRiRUJ5WldaekwyaGxZV1J6TDNOaWIyMHcKT0FZS0t3WUJCQUdEdnpBQkV3UXFEQ2d5TW1ZM1pqRTRPRE0wTmpjeE5UVTBaalptTXpkaE9XTXdaakZrTm1NdwpZakZtTWpReU1XWTBNQ0VHQ2lzR0FRUUJnNzh3QVJRRUV3d1JkMjl5YTJac2IzZGZaR2x6Y0dGMFkyZ3dZd1lLCkt3WUJCQUdEdnpBQkZRUlZERk5vZEhSd2N6b3ZMMmRwZEdoMVlpNWpiMjB2YkdsaGRISnBieTluYUMxMGNuVnoKZEdWa0xXSjFhV3hrY3kxaGNIQXZZV04wYVc5dWN5OXlkVzV6THpVd09UTXdOakF6TWpZdllYUjBaVzF3ZEhNdgpNVENCaVFZS0t3WUJCQUhXZVFJRUFnUjdCSGtBZHdCMUFOMDlNR3JHeHhFeVl4a2VISmxuTndLaVNsNjQzanl0Ci80ZUtjb0F2S2U2T0FBQUJpRmp2Zm5BQUFBUURBRVl3UkFJZ0dTQ1gwa0tRNy9sTWNtS2tJeG1pTmV5NTBCN0MKZ2dGakQ3VWVIWE52Q0JBQ0lCRjMvVEpVKzU3ZktHQk5DODNLT0dUdndKKzF6TXVlRUREeVdxaFBScTdWTUFvRwpDQ3FHU000OUJBTURBMmNBTUdRQ01EWHUzVlNZNVdqMjZxbFRURFRyUXYxRFBicnlLRnJkTzhlY3EvQ2p1dUJsCkZieDRkUys0VXpIL21xTXZLVUliZHdJd2ZqWlpwMWJCMk9ESktoQ3FKMlNwQW1SKzh0QVRIWlRQZk1GejJKV3EKVW5veXdhdWJQdVBnYnB2MVIzSzdSenhPCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" + } + }, + "LogIndex": 21763978, + "IntegratedTime": 1685119271, + "UUID": "24296fb24b8ad77aa1b89ec050ab378e81752a59147a1398243d081e88512e91cee2918855ea5e16", + "LogID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d" + } +} \ No newline at end of file