diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 3c60bf04..51e37660 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,3 +29,11 @@ jobs: - name: Make build run: PATH=$PATH:$PWD:/home/runner/.local/bin make build + + - name: Setup Regal + uses: StyraInc/setup-regal@v1 + with: + version: v0.24.0 + + - name: Regal Lint + run: regal lint --format github . diff --git a/api_authz/docker/docker-compose.yaml b/api_authz/docker/docker-compose.yaml index 40a3e9c1..29cf3cb8 100644 --- a/api_authz/docker/docker-compose.yaml +++ b/api_authz/docker/docker-compose.yaml @@ -1,6 +1,6 @@ services: opa: - image: openpolicyagent/opa:0.40.0-rootless + image: openpolicyagent/opa:0.67.0 ports: - "8181:8181" command: diff --git a/api_authz/docker/policy/example-hr.rego b/api_authz/docker/policy/example-hr.rego index 497564ad..964f5559 100644 --- a/api_authz/docker/policy/example-hr.rego +++ b/api_authz/docker/policy/example-hr.rego @@ -1,13 +1,13 @@ -package httpapi.authz +package httpapi.authz.hr + +import rego.v1 # Allow HR members to get anyone's salary. -allow { - input.method == "GET" - input.path = ["finance", "salary", _] - input.user == hr[_] +allow if { + input.method == "GET" + input.path = ["finance", "salary", _] + input.user in members } # David is the only member of HR. -hr = [ - "david", -] +members := ["david"] diff --git a/api_authz/docker/policy/example-jwt.rego b/api_authz/docker/policy/example-jwt.rego index 22839085..a057cbd8 100644 --- a/api_authz/docker/policy/example-jwt.rego +++ b/api_authz/docker/policy/example-jwt.rego @@ -1,37 +1,35 @@ -package httpapi.authz +package httpapi.authz.jwt -default allow = false +import rego.v1 + +default allow := false # Allow users to get their own salaries. -allow { - some username - input.method == "GET" - input.path = ["finance", "salary", username] - token.payload.user == username - user_owns_token +allow if { + input.method == "GET" + input.path == ["finance", "salary", token.payload.user] + user_owns_token } # Allow managers to get their subordinate' salaries. -allow { - some username - input.method == "GET" - input.path = ["finance", "salary", username] - token.payload.subordinates[_] == username - user_owns_token +allow if { + some username + input.method == "GET" + input.path = ["finance", "salary", username] + username in token.payload.subordinates + user_owns_token } # Allow HR members to get anyone's salary. -allow { - input.method == "GET" - input.path = ["finance", "salary", _] - token.payload.hr == true - user_owns_token +allow if { + input.method == "GET" + input.path = ["finance", "salary", _] + token.payload.hr == true + user_owns_token } # Ensure that the token was issued to the user supplying it. -user_owns_token { input.user == token.payload.azp } +user_owns_token if input.user == token.payload.azp # Helper to get the token payload. -token = {"payload": payload} { - [_, payload, _] := io.jwt.decode(input.token) -} +token := {"payload": io.jwt.decode(input.token)[1]} diff --git a/api_authz/docker/policy/example.rego b/api_authz/docker/policy/example.rego index 97c0681b..2a0c2afa 100644 --- a/api_authz/docker/policy/example.rego +++ b/api_authz/docker/policy/example.rego @@ -1,7 +1,9 @@ package httpapi.authz +import rego.v1 + # bob is alice's manager, and betty is charlie's. -subordinates = {"alice": [], "charlie": [], "bob": ["alice"], "betty": ["charlie"]} +subordinates := {"alice": [], "charlie": [], "bob": ["alice"], "betty": ["charlie"]} # HTTP API request # input = { @@ -10,20 +12,18 @@ subordinates = {"alice": [], "charlie": [], "bob": ["alice"], "betty": ["charlie # "method": "GET" # } -default allow = false +default allow := false # Allow users to get their own salaries. -allow { - some username - input.method == "GET" - input.path = ["finance", "salary", username] - input.user == username +allow if { + input.method == "GET" + input.path == ["finance", "salary", input.user] } # Allow managers to get their subordinates' salaries. -allow { - some username - input.method == "GET" - input.path = ["finance", "salary", username] - subordinates[input.user][_] == username +allow if { + some username + input.method == "GET" + input.path = ["finance", "salary", username] + username in subordinates[input.user] } diff --git a/cloud-foundry/polices/cipher/cipher_test.rego b/cloud-foundry/polices/cipher/cipher_test.rego index 05d8a667..76b37aff 100644 --- a/cloud-foundry/polices/cipher/cipher_test.rego +++ b/cloud-foundry/polices/cipher/cipher_test.rego @@ -1,9 +1,19 @@ -package main - -test_if_ciphers_match { - deny_if_ciphers_missing[_] with input as { - ".properties.gorouter_ssl_ciphers": { - "value": "ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - } - } -} \ No newline at end of file +package main_test + +import rego.v1 + +import data.main + +test_if_ciphers_match if { + val := "ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" + obj := {".properties.gorouter_ssl_ciphers": {"value": val}} + + expect := concat("\n", [ + "expected cipher configuration of: ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + " please update the value following this json path: [\".properties.gorouter_ssl_ciphers\", \"value\"]", + ]) + + result := main.deny_if_ciphers_missing with input as obj + + expect in result +} diff --git a/cloud-foundry/polices/pas/cert/certificate.rego b/cloud-foundry/polices/pas/cert/certificate.rego index 1c34f62c..db24656e 100644 --- a/cloud-foundry/polices/pas/cert/certificate.rego +++ b/cloud-foundry/polices/pas/cert/certificate.rego @@ -1,65 +1,66 @@ package cert -parse_certificate(cert) = parsedCertificate { - strippedCert := replace(replace(cert, "-----END CERTIFICATE-----", ""), "-----BEGIN CERTIFICATE-----", "") - parsedCertificate := crypto.x509.parse_certificates(strippedCert) +import rego.v1 + +parse_certificate(cert) := parsed_certificate if { + stripped_cert := replace(replace(cert, "-----END CERTIFICATE-----", ""), "-----BEGIN CERTIFICATE-----", "") + parsed_certificate := crypto.x509.parse_certificates(stripped_cert) } -separate_certs(certChain) = cleanedCerts { - addDelimeter := replace(certChain, "-----END CERTIFICATE-----\n", "-----END CERTIFICATE-----\n&&&&") - splitCerts := split(addDelimeter, "&&&&") - count(splitCerts) > 0 +separate_certs(cert_chain) := cleaned_certs if { + add_delimeter := replace(cert_chain, "-----END CERTIFICATE-----\n", "-----END CERTIFICATE-----\n&&&&") + split_certs := split(add_delimeter, "&&&&") + count(split_certs) > 0 - cleanedCerts := array.slice(splitCerts, 0, count(splitCerts) - 1) + cleaned_certs := array.slice(split_certs, 0, count(split_certs) - 1) } -get_certificate_expiry(rawCertChain) = expiryDate { - certArray := separate_certs(rawCertChain) - parsedCerts := [parsedCert | - cert := certArray[_] - parsedCert := parse_certificate(cert) - ] +expiry(raw_cert_chain) := expiry_date if { + cert_array := separate_certs(raw_cert_chain) + parsed_certs := [parsed_cert | + some cert in cert_array + parsed_cert := parse_certificate(cert) + ] - expiryDate := [expiryDate | - expiryDate := parsedCerts[_][_].NotAfter - ] + expiry_date := [expiry_date | + expiry_date := parsed_certs[_][_].NotAfter + ] } -determine_if_expired(dates) = certsForRenewal { - thirty_days_in_nanoseconds := 2.592e+15 +determine_if_expired(dates) := certs_for_renewal if { + thirty_days_in_nanoseconds := 2.592e+15 - currentTime_nano := time.now_ns() - certsForRenewal := [expired | - date := dates[_] - certExpiryDate_nano := time.parse_rfc3339_ns(date) - timeDelta := certExpiryDate_nano - currentTime_nano - timeDelta <= thirty_days_in_nanoseconds + certs_for_renewal := [expired | + some date in dates + cert_expiry_date_nano := time.parse_rfc3339_ns(date) + time_delta := cert_expiry_date_nano - time.now_ns() + time_delta <= thirty_days_in_nanoseconds - expired := { - "date": date, - "expired": timeDelta <= thirty_days_in_nanoseconds, - } - ] + expired := { + "date": date, + "expired": time_delta <= thirty_days_in_nanoseconds, + } + ] } -deny_certs_not_present[msg] { - exists := [certs | - certs := input.certs - ] #you will need to provide a path to a cert +deny_certs_not_present contains msg if { + exists := [certs | + certs := input.certs + ] # you will need to provide a path to a cert - count(exists) == 0 + count(exists) == 0 - msg = sprintf("No certs in provided, either in path or input object: %v", [exists]) + msg = sprintf("No certs in provided, either in path or input object: %v", [exists]) } -deny_thirty_days[msg] { - # must manually define path to cert. JSON input - # key values are accessed using bracket notation rather than dot "." notation - certs := input.certs #you will need to provide a path to a cert - expirys := get_certificate_expiry(certs) - isExpired := determine_if_expired(expirys) +deny_thirty_days contains msg if { + # must manually define path to cert. JSON input + # key values are accessed using bracket notation rather than dot "." notation + certs := input.certs # you will need to provide a path to a cert + expirys := expiry(certs) + is_expired := determine_if_expired(expirys) - count(isExpired) > 0 + count(is_expired) > 0 - msg = sprintf("Your certificate expires on this date %v please update cert", [isExpired]) -} \ No newline at end of file + msg = sprintf("Your certificate expires on this date %v please update cert", [is_expired]) +} diff --git a/cloud-foundry/polices/pas/cert/certificate_test.rego b/cloud-foundry/polices/pas/cert/certificate_test.rego index 5da18045..e4f4d366 100644 --- a/cloud-foundry/polices/pas/cert/certificate_test.rego +++ b/cloud-foundry/polices/pas/cert/certificate_test.rego @@ -1,90 +1,123 @@ -package cert +package cert_test -test_expired_cert_is_expired { +import rego.v1 - expiryDate := ["2019-09-13T15:16:21Z"] - actual := determine_if_expired(expiryDate) - expected := [{ - "date": "2019-09-13T15:16:21Z", - "expired": true - }] +import data.cert - actual == expected -} - -test_non_expired_cert_is_not_expired { - - expiryDate := ["2050-09-13T15:16:21Z"] - actual := determine_if_expired(expiryDate) - expected := [] +test_expired_cert_is_expired if { + expiry_date := ["2019-09-13T15:16:21Z"] + actual := cert.determine_if_expired(expiry_date) + expected := [{ + "date": "2019-09-13T15:16:21Z", + "expired": true, + }] - actual == expected + actual == expected } -test_get_certificate_expiry { - actual := get_certificate_expiry(fakeCert) - expected := "2019-10-13T15:16:21Z" +test_non_expired_cert_is_not_expired if { + expiry_date := ["2050-09-13T15:16:21Z"] + actual := cert.determine_if_expired(expiry_date) + expected := [] - actual[_] == expected - + actual == expected } -test_get_certificate_expiry_two { - actual := get_certificate_expiry(fakeCert2) - expected := "2018-03-18T15:40:19Z" +test_get_certificate_expiry if { + "2019-10-13T15:16:21Z" in cert.expiry(fake_cert) +} - actual[_] == expected +test_get_certificate_expiry_two if { + "2018-03-18T15:40:19Z" in cert.expiry(fake_cert2) } -test_get_multiple_expiry { - mockCerts := [fakeCert, fakeCert2] - expected := [ - "2019-10-13T15:16:21Z", - "2018-03-18T15:40:19Z", - ] +test_get_multiple_expiry if { + mock_certs := [fake_cert, fake_cert2] + expected := [ + "2019-10-13T15:16:21Z", + "2018-03-18T15:40:19Z", + ] - actual := get_certificate_expiry(concat("", mockCerts)) + actual := cert.expiry(concat("", mock_certs)) - actual == expected + actual == expected } -test_expiring_dates_return_true { - - expiryDate := ["2019-09-13T15:16:21Z", "2019-10-13T15:16:21Z"] - actual := determine_if_expired(expiryDate) - expected := [ - { - "date": "2019-09-13T15:16:21Z", - "expired": true - }, - { - "date": "2019-10-13T15:16:21Z", - "expired": true - } - ] - - actual == expected +test_expiring_dates_return_true if { + expiry_date := ["2019-09-13T15:16:21Z", "2019-10-13T15:16:21Z"] + actual := cert.determine_if_expired(expiry_date) + expected := [ + { + "date": "2019-09-13T15:16:21Z", + "expired": true, + }, + { + "date": "2019-10-13T15:16:21Z", + "expired": true, + }, + ] + + actual == expected } -test_cert_separation { - mockCerts := certChain - expected := [ - fakeCert, - fakeCert2, - ] - actual := separate_certs(mockCerts) - - actual == expected +test_cert_separation if { + expected := [ + fake_cert, + fake_cert2, + ] + actual := cert.separate_certs(cert_chain) + actual == expected } -test_fail_on_no_certs { - actual := get_certificate_expiry("meow") - expected := 0 +test_fail_on_no_certs if { + actual := cert.expiry("meow") + expected := 0 - count(actual) == expected + count(actual) == expected } -fakeCert ="-----BEGIN CERTIFICATE-----\nMIIESjCCAzKgAwIBAgIJAJpBvIaxZbsqMA0GCSqGSIb3DQEBCwUAMIGYMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCTlkxETAPBgNVBAcMCE5ldyBZb3JrMRQwEgYDVQQK\nDAtNaXR0ZW5zIE9yZzEWMBQGA1UECwwNTGFicyBQbGF0Zm9ybTEZMBcGA1UEAwwQ\nd2ViLmN1c3RvbWVyLm9yZzEgMB4GCSqGSIb3DQEJARYRZmFrZXlAbWNmYWtlcy5j\nb20wHhcNMTkwOTEzMTUxNjIxWhcNMTkxMDEzMTUxNjIxWjCBmDELMAkGA1UEBhMC\nVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9yazEUMBIGA1UECgwLTWl0\ndGVucyBPcmcxFjAUBgNVBAsMDUxhYnMgUGxhdGZvcm0xGTAXBgNVBAMMEHdlYi5j\ndXN0b21lci5vcmcxIDAeBgkqhkiG9w0BCQEWEWZha2V5QG1jZmFrZXMuY29tMIIB\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr2TolHBt18D9ihtN+vvksLu\nv+O8qpfzSbpj6WdOSNCsUSQiCVOeZMChoq4Lm7e7WHruoCj/el7+FxW6To/OkJwh\nLSkfCBDYqqGq7AwTLuZ2/Hu/l93mqPkHGCQzYAu0R4NCh97uWa5PKdMqJKf7Bmrp\neMyLbsjEpImVw6hnEK7zllrzZDNLEXxhlakLw9TV2VfghMdo7TKqPYvnmzu/n+Zz\nwKK0FQbc0YJoka/tMm/qe1GOnTSNIr7vp+ovPGh46/VU36YiKAiKfbWn3X6EPqSu\nJabD55LBUQQRrrsLlKgoNOWbjyG73fJ8xd0/E8vtDyj9JgidfOikKcR33F/O/wID\nAQABo4GUMIGRMA4GA1UdDwEB/wQEAwIFoDB0BgNVHREEbTBrghYqLnN5cy53ZWIu\nY3VzdG9tZXIub3JnghcqLmFwcHMud2ViLmN1c3RvbWVyLm9yZ4IcKi5sb2dpbi5z\neXMud2ViLmN1c3RvbWVyLm9yZ4IaKi51YWEuc3lzLndlYi5jdXN0b21lci5vcmcw\nCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAhUuD26d2hCfrq3OytwZMTa23\nuZVKHxM51EnovPwUHDIAcNYAF3pkcn4eEZI4hT0aQMq5O27r6wVwSTWywHZLw378\nl5UwYBXUXtbuAyGXDgKDAJGUcGQ1Z7fQ0YtXXMUAutxNpc54hjaEdgAfyxk3kOmT\n/k6mWGzaYkxGmuxwh4uM831fEeQaKjBdlBuPggUa0ZKpF/6J/vFGCiqz7cfI1Pde\nxuaRoq5on8aUDrHW5wjGwxLncivpyDP2Pt3FEKw5tGlQCU0+b3JZBEYmAfgENkEf\nK1Qp01rVVJ0+0lPI7M5cDEQhJtEg2PXzzy/inGK28JcLmNXY88BP5WLPou1JGw==\n-----END CERTIFICATE-----\n" -fakeCert2 = "-----BEGIN CERTIFICATE-----\nMIICMzCCAZygAwIBAgIJALiPnVsvq8dsMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV\nBAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNVBAcTA2ZvbzEMMAoGA1UEChMDZm9v\nMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2ZvbzAeFw0xMzAzMTkxNTQwMTlaFw0x\nODAzMTgxNTQwMTlaMFMxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNV\nBAcTA2ZvbzEMMAoGA1UEChMDZm9vMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2Zv\nbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzdGfxi9CNbMf1UUcvDQh7MYB\nOveIHyc0E0KIbhjK5FkCBU4CiZrbfHagaW7ZEcN0tt3EvpbOMxxc/ZQU2WN/s/wP\nxph0pSfsfFsTKM4RhTWD2v4fgk+xZiKd1p0+L4hTtpwnEw0uXRVd0ki6muwV5y/P\n+5FHUeldq+pgTcgzuK8CAwEAAaMPMA0wCwYDVR0PBAQDAgLkMA0GCSqGSIb3DQEB\nBQUAA4GBAJiDAAtY0mQQeuxWdzLRzXmjvdSuL9GoyT3BF/jSnpxz5/58dba8pWen\nv3pj4P3w5DoOso0rzkZy2jEsEitlVM2mLSbQpMM+MUVQCQoiG6W9xuCFuxSrwPIS\npAqEAuV4DNoxQKKWmhVv+J0ptMWD25Pnpxeq5sXzghfJnslJlQND\n-----END CERTIFICATE-----\n" -certChain = "-----BEGIN CERTIFICATE-----\nMIIESjCCAzKgAwIBAgIJAJpBvIaxZbsqMA0GCSqGSIb3DQEBCwUAMIGYMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCTlkxETAPBgNVBAcMCE5ldyBZb3JrMRQwEgYDVQQK\nDAtNaXR0ZW5zIE9yZzEWMBQGA1UECwwNTGFicyBQbGF0Zm9ybTEZMBcGA1UEAwwQ\nd2ViLmN1c3RvbWVyLm9yZzEgMB4GCSqGSIb3DQEJARYRZmFrZXlAbWNmYWtlcy5j\nb20wHhcNMTkwOTEzMTUxNjIxWhcNMTkxMDEzMTUxNjIxWjCBmDELMAkGA1UEBhMC\nVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9yazEUMBIGA1UECgwLTWl0\ndGVucyBPcmcxFjAUBgNVBAsMDUxhYnMgUGxhdGZvcm0xGTAXBgNVBAMMEHdlYi5j\ndXN0b21lci5vcmcxIDAeBgkqhkiG9w0BCQEWEWZha2V5QG1jZmFrZXMuY29tMIIB\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr2TolHBt18D9ihtN+vvksLu\nv+O8qpfzSbpj6WdOSNCsUSQiCVOeZMChoq4Lm7e7WHruoCj/el7+FxW6To/OkJwh\nLSkfCBDYqqGq7AwTLuZ2/Hu/l93mqPkHGCQzYAu0R4NCh97uWa5PKdMqJKf7Bmrp\neMyLbsjEpImVw6hnEK7zllrzZDNLEXxhlakLw9TV2VfghMdo7TKqPYvnmzu/n+Zz\nwKK0FQbc0YJoka/tMm/qe1GOnTSNIr7vp+ovPGh46/VU36YiKAiKfbWn3X6EPqSu\nJabD55LBUQQRrrsLlKgoNOWbjyG73fJ8xd0/E8vtDyj9JgidfOikKcR33F/O/wID\nAQABo4GUMIGRMA4GA1UdDwEB/wQEAwIFoDB0BgNVHREEbTBrghYqLnN5cy53ZWIu\nY3VzdG9tZXIub3JnghcqLmFwcHMud2ViLmN1c3RvbWVyLm9yZ4IcKi5sb2dpbi5z\neXMud2ViLmN1c3RvbWVyLm9yZ4IaKi51YWEuc3lzLndlYi5jdXN0b21lci5vcmcw\nCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAhUuD26d2hCfrq3OytwZMTa23\nuZVKHxM51EnovPwUHDIAcNYAF3pkcn4eEZI4hT0aQMq5O27r6wVwSTWywHZLw378\nl5UwYBXUXtbuAyGXDgKDAJGUcGQ1Z7fQ0YtXXMUAutxNpc54hjaEdgAfyxk3kOmT\n/k6mWGzaYkxGmuxwh4uM831fEeQaKjBdlBuPggUa0ZKpF/6J/vFGCiqz7cfI1Pde\nxuaRoq5on8aUDrHW5wjGwxLncivpyDP2Pt3FEKw5tGlQCU0+b3JZBEYmAfgENkEf\nK1Qp01rVVJ0+0lPI7M5cDEQhJtEg2PXzzy/inGK28JcLmNXY88BP5WLPou1JGw==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICMzCCAZygAwIBAgIJALiPnVsvq8dsMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV\nBAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNVBAcTA2ZvbzEMMAoGA1UEChMDZm9v\nMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2ZvbzAeFw0xMzAzMTkxNTQwMTlaFw0x\nODAzMTgxNTQwMTlaMFMxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNV\nBAcTA2ZvbzEMMAoGA1UEChMDZm9vMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2Zv\nbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzdGfxi9CNbMf1UUcvDQh7MYB\nOveIHyc0E0KIbhjK5FkCBU4CiZrbfHagaW7ZEcN0tt3EvpbOMxxc/ZQU2WN/s/wP\nxph0pSfsfFsTKM4RhTWD2v4fgk+xZiKd1p0+L4hTtpwnEw0uXRVd0ki6muwV5y/P\n+5FHUeldq+pgTcgzuK8CAwEAAaMPMA0wCwYDVR0PBAQDAgLkMA0GCSqGSIb3DQEB\nBQUAA4GBAJiDAAtY0mQQeuxWdzLRzXmjvdSuL9GoyT3BF/jSnpxz5/58dba8pWen\nv3pj4P3w5DoOso0rzkZy2jEsEitlVM2mLSbQpMM+MUVQCQoiG6W9xuCFuxSrwPIS\npAqEAuV4DNoxQKKWmhVv+J0ptMWD25Pnpxeq5sXzghfJnslJlQND\n-----END CERTIFICATE-----\n" \ No newline at end of file +fake_cert := `-----BEGIN CERTIFICATE----- +MIIESjCCAzKgAwIBAgIJAJpBvIaxZbsqMA0GCSqGSIb3DQEBCwUAMIGYMQswCQYD +VQQGEwJVUzELMAkGA1UECAwCTlkxETAPBgNVBAcMCE5ldyBZb3JrMRQwEgYDVQQK +DAtNaXR0ZW5zIE9yZzEWMBQGA1UECwwNTGFicyBQbGF0Zm9ybTEZMBcGA1UEAwwQ +d2ViLmN1c3RvbWVyLm9yZzEgMB4GCSqGSIb3DQEJARYRZmFrZXlAbWNmYWtlcy5j +b20wHhcNMTkwOTEzMTUxNjIxWhcNMTkxMDEzMTUxNjIxWjCBmDELMAkGA1UEBhMC +VVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9yazEUMBIGA1UECgwLTWl0 +dGVucyBPcmcxFjAUBgNVBAsMDUxhYnMgUGxhdGZvcm0xGTAXBgNVBAMMEHdlYi5j +dXN0b21lci5vcmcxIDAeBgkqhkiG9w0BCQEWEWZha2V5QG1jZmFrZXMuY29tMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr2TolHBt18D9ihtN+vvksLu +v+O8qpfzSbpj6WdOSNCsUSQiCVOeZMChoq4Lm7e7WHruoCj/el7+FxW6To/OkJwh +LSkfCBDYqqGq7AwTLuZ2/Hu/l93mqPkHGCQzYAu0R4NCh97uWa5PKdMqJKf7Bmrp +eMyLbsjEpImVw6hnEK7zllrzZDNLEXxhlakLw9TV2VfghMdo7TKqPYvnmzu/n+Zz +wKK0FQbc0YJoka/tMm/qe1GOnTSNIr7vp+ovPGh46/VU36YiKAiKfbWn3X6EPqSu +JabD55LBUQQRrrsLlKgoNOWbjyG73fJ8xd0/E8vtDyj9JgidfOikKcR33F/O/wID +AQABo4GUMIGRMA4GA1UdDwEB/wQEAwIFoDB0BgNVHREEbTBrghYqLnN5cy53ZWIu +Y3VzdG9tZXIub3JnghcqLmFwcHMud2ViLmN1c3RvbWVyLm9yZ4IcKi5sb2dpbi5z +eXMud2ViLmN1c3RvbWVyLm9yZ4IaKi51YWEuc3lzLndlYi5jdXN0b21lci5vcmcw +CQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAhUuD26d2hCfrq3OytwZMTa23 +uZVKHxM51EnovPwUHDIAcNYAF3pkcn4eEZI4hT0aQMq5O27r6wVwSTWywHZLw378 +l5UwYBXUXtbuAyGXDgKDAJGUcGQ1Z7fQ0YtXXMUAutxNpc54hjaEdgAfyxk3kOmT +/k6mWGzaYkxGmuxwh4uM831fEeQaKjBdlBuPggUa0ZKpF/6J/vFGCiqz7cfI1Pde +xuaRoq5on8aUDrHW5wjGwxLncivpyDP2Pt3FEKw5tGlQCU0+b3JZBEYmAfgENkEf +K1Qp01rVVJ0+0lPI7M5cDEQhJtEg2PXzzy/inGK28JcLmNXY88BP5WLPou1JGw== +-----END CERTIFICATE----- +` + +fake_cert2 := `-----BEGIN CERTIFICATE----- +MIICMzCCAZygAwIBAgIJALiPnVsvq8dsMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV +BAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNVBAcTA2ZvbzEMMAoGA1UEChMDZm9v +MQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2ZvbzAeFw0xMzAzMTkxNTQwMTlaFw0x +ODAzMTgxNTQwMTlaMFMxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNV +BAcTA2ZvbzEMMAoGA1UEChMDZm9vMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2Zv +bzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzdGfxi9CNbMf1UUcvDQh7MYB +OveIHyc0E0KIbhjK5FkCBU4CiZrbfHagaW7ZEcN0tt3EvpbOMxxc/ZQU2WN/s/wP +xph0pSfsfFsTKM4RhTWD2v4fgk+xZiKd1p0+L4hTtpwnEw0uXRVd0ki6muwV5y/P ++5FHUeldq+pgTcgzuK8CAwEAAaMPMA0wCwYDVR0PBAQDAgLkMA0GCSqGSIb3DQEB +BQUAA4GBAJiDAAtY0mQQeuxWdzLRzXmjvdSuL9GoyT3BF/jSnpxz5/58dba8pWen +v3pj4P3w5DoOso0rzkZy2jEsEitlVM2mLSbQpMM+MUVQCQoiG6W9xuCFuxSrwPIS +pAqEAuV4DNoxQKKWmhVv+J0ptMWD25Pnpxeq5sXzghfJnslJlQND +-----END CERTIFICATE----- +` + +cert_chain := concat("", [fake_cert, fake_cert2]) diff --git a/cloud-foundry/polices/pas/cipher/check_cipher.rego b/cloud-foundry/polices/pas/cipher/check_cipher.rego index 9bf2da45..4ed6a1ac 100644 --- a/cloud-foundry/polices/pas/cipher/check_cipher.rego +++ b/cloud-foundry/polices/pas/cipher/check_cipher.rego @@ -1,23 +1,23 @@ package main -find(json, desiredValue) = route { - some path - walk(json, [path, desiredValue]) +import rego.v1 - - count(path) != 0 - route := path +find(json, desired_value) := path if { + some path + walk(json, [path, desired_value]) } -deny_if_ciphers_missing[msg] { - desiredCipher := "ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" - routeToValue := find(input, desiredCipher) +deny_if_ciphers_missing contains msg if { + desired_cipher := "ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" + route_to_value := find(input, desired_cipher) - # count(routeToValue) < 1 - true + # count(routeToValue) < 1 - msg = sprintf("expected cipher configuration of: %v\n please update the value following this json path: %v", [desiredCipher, routeToValue]) + msg := sprintf( + "expected cipher configuration of: %v\n please update the value following this json path: %v", + [desired_cipher, route_to_value], + ) } -#the above is closer to what i want -#now I'm getting the path to the output \ No newline at end of file +# the above is closer to what i want +# now I'm getting the path to the output diff --git a/cloud-foundry/polices/pas/cipher/cipher_test.rego b/cloud-foundry/polices/pas/cipher/cipher_test.rego index 1a616885..5adaf5ab 100644 --- a/cloud-foundry/polices/pas/cipher/cipher_test.rego +++ b/cloud-foundry/polices/pas/cipher/cipher_test.rego @@ -1,9 +1,19 @@ -package main - -test_if_ciphers_match { - deny_if_ciphers_missing[_] with input as { - ".properties.gorouter_ssl_ciphers": { - "value": "ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - } - } -} \ No newline at end of file +package main_test + +import rego.v1 + +import data.main + +test_if_ciphers_match if { + val := "ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" + obj := {".properties.gorouter_ssl_ciphers": {"value": val}} + + result := main.deny_if_ciphers_missing with input as obj + + expect := concat("\n", [ + "expected cipher configuration of: ECDHE-RSA-AES128-GCM-SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + " please update the value following this json path: [\".properties.gorouter_ssl_ciphers\", \"value\"]", + ]) + + result[expect] +} diff --git a/cloud-foundry/polices/pas/combine.rego b/cloud-foundry/polices/pas/combine.rego deleted file mode 100644 index 08b0128d..00000000 --- a/cloud-foundry/polices/pas/combine.rego +++ /dev/null @@ -1,16 +0,0 @@ -package main - -deny_if_extensions_do_not_match[msg] { - pasExtensions := [ key | - input[_]["resource-config"]["router"]["additional_vm_extensions"][i] - key := input[_]["resource-config"]["router"]["additional_vm_extensions"][i] - ] - cfExtensions := [ key | - input[_]["resource-config"]["router"]["additional_vm_extensions"][i] - key := input[_]["resource-config"]["router"]["additional_vm_extensions"][i] - ] - pasExtensions != cfExtensions - msg = sprintf("Expected vm extension to match instead got and %v for PAS and %v", [pasExtensions, cfExtensions]) -} - -#this currently doesn't work because it cannot \ No newline at end of file diff --git a/cloud-foundry/polices/pas/credhub-key/credhub_key.rego b/cloud-foundry/polices/pas/credhub-key/credhub_key.rego index 6b2a18cd..ea1a5c83 100644 --- a/cloud-foundry/polices/pas/credhub-key/credhub_key.rego +++ b/cloud-foundry/polices/pas/credhub-key/credhub_key.rego @@ -1,18 +1,22 @@ package credhub -deny_if_not_exactly_one_primary[msg] { - keys := [key | - key := input["product-properties"][".properties.credhub_key_encryption_passwords"].value[i].primary - ] +import rego.v1 - count(keys) < 1 - count(keys) > 1 - msg = sprintf("Must have exactly one primary encryption key for credhub, found %d", [count(keys)]) +deny_if_not_exactly_one_primary contains msg if { + keys := [key.primary | + some key in input["product-properties"][".properties.credhub_key_encryption_passwords"].value + ] + + count(keys) != 1 + + msg := sprintf("Must have exactly one primary encryption key for credhub, found %d", [count(keys)]) } -deny_not_enough_chars[msg] { - some i - input["product-properties"][".properties.credhub_key_encryption_passwords"].value[i].primary - key := input["product-properties"][".properties.credhub_key_encryption_passwords"].value[i].key.secret - count(key) < 20 - msg := sprintf("Primary key must be at least 20 characters, found %v", [count(key)]) + +deny_not_enough_chars contains msg if { + some val in input["product-properties"][".properties.credhub_key_encryption_passwords"].value + val.primary + + count(val.key.secret) < 20 + + msg := sprintf("Primary key must be at least 20 characters, found %v", [count(val.key.secret)]) } diff --git a/cloud-foundry/polices/pas/credhub-key/credhub_key_test.rego b/cloud-foundry/polices/pas/credhub-key/credhub_key_test.rego index 9773f69a..86cebe5b 100644 --- a/cloud-foundry/polices/pas/credhub-key/credhub_key_test.rego +++ b/cloud-foundry/polices/pas/credhub-key/credhub_key_test.rego @@ -1,19 +1,15 @@ -package credhub +package credhub_test -test_deny_credhub_suite { - deny_if_not_exactly_one_primary with input as pasKey - deny_not_enough_chars with input as pasKey +import rego.v1 + +import data.credhub + +test_deny_credhub_suite if { + credhub.deny_if_not_exactly_one_primary with input as pas_key + credhub.deny_not_enough_chars with input as pas_key } -pasKey = {"product-properties": { - ".properties.credhub_hsm_provider_partition_password": {"value": [{"primary": false}]}, - ".properties.credhub_key_encryption_passwords": {"value": [{"primary": "1234567890123456789"}]} +pas_key := {"product-properties": { + ".properties.credhub_hsm_provider_partition_password": {"value": [{"primary": false}]}, + ".properties.credhub_key_encryption_passwords": {"value": [{"primary": "1234567890123456789"}]}, }} - -newJson = {"security-group": [ - {"ac001": "1232"}, - {"ac003": { - "map": "again", - "and": ["yet", "again"], - }}, -]} diff --git a/cloud-foundry/polices/pas/diego/diego.rego b/cloud-foundry/polices/pas/diego/diego.rego index ee019324..6ef82c02 100644 --- a/cloud-foundry/polices/pas/diego/diego.rego +++ b/cloud-foundry/polices/pas/diego/diego.rego @@ -1,13 +1,15 @@ package main -find_vm_type(dataObj, service) = vmType { - find_VMType := [type | - dataObj.resources[i].identifier == service - type := dataObj.resources[i] - ] - vmType := { - "resource": find_VMType, - "present": count(find_VMType) > 0 - } -} +import rego.v1 + +find_vm_type(data_obj, service) := vm_type if { + find_vm_type := [resource | + some resource in data_obj.resources + resource.identifier == service + ] + vm_type := { + "resource": find_vm_type, + "present": count(find_vm_type) > 0, + } +} diff --git a/cloud-foundry/polices/pas/diego/diego_cell_test.rego b/cloud-foundry/polices/pas/diego/diego_cell_test.rego index e5494b05..ed51db02 100644 --- a/cloud-foundry/polices/pas/diego/diego_cell_test.rego +++ b/cloud-foundry/polices/pas/diego/diego_cell_test.rego @@ -1,67 +1,71 @@ -package main +package main_test -test_vm_type_is_present { - expected := { - "resource": [{ - "identifier": "diego_cell", - "description": "Diego Cell", - "instances": "", - "instances_best_fit": 0, - "instance_type_id": "medium", - "instance_type_best_fit": "xlarge.disk", - }], - "present": true, - } +import rego.v1 - actual := find_vm_type(mock_api_call, "diego_cell") +import data.main - actual == expected +test_vm_type_is_present if { + expected := { + "resource": [{ + "identifier": "diego_cell", + "description": "Diego Cell", + "instances": "", + "instances_best_fit": 0, + "instance_type_id": "medium", + "instance_type_best_fit": "xlarge.disk", + }], + "present": true, + } + + actual := main.find_vm_type(mock_api_call, "diego_cell") + + actual == expected } -test_vm_type_is_absent { - expected := { - "resource": [], - "present": false, - } +test_vm_type_is_absent if { + expected := { + "resource": [], + "present": false, + } - actual := find_vm_type(mock_bad_api_call, "diego_cell") + actual := main.find_vm_type(mock_bad_api_call, "diego_cell") - actual == expected + actual == expected } -mock_bad_api_call = {"resources": []} +mock_bad_api_call := {"resources": []} -mock_api_call = {"resources": [ - { - "identifier": "mysql_monitor", - "description": "Monitors the MySQL Cluster", - "instances": "", - "instances_best_fit": 1, - "instance_type_id": "", - "instance_type_best_fit": "micro", - }, - { - "identifier": "clock_global", - "description": "Schedules asynchronous tasks for cloud controller", - "instances": "", - "instances_best_fit": 0, - "instance_type_id": "", - "instance_type_best_fit": "medium.disk", - }, - { - "identifier": "cloud_controller_worker", - "description": "Worker for cloud controller asynchronous tasks", - "instances": "", - "instances_best_fit": 0, - "instance_type_id": "", - "instance_type_best_fit": "micro", - }, - { - "identifier": "diego_cell", - "description": "Diego Cell", - "instances": "", - "instances_best_fit": 0, - "instance_type_id": "medium", - "instance_type_best_fit": "xlarge.disk", - }, -]} \ No newline at end of file +mock_api_call := {"resources": [ + { + "identifier": "mysql_monitor", + "description": "Monitors the MySQL Cluster", + "instances": "", + "instances_best_fit": 1, + "instance_type_id": "", + "instance_type_best_fit": "micro", + }, + { + "identifier": "clock_global", + "description": "Schedules asynchronous tasks for cloud controller", + "instances": "", + "instances_best_fit": 0, + "instance_type_id": "", + "instance_type_best_fit": "medium.disk", + }, + { + "identifier": "cloud_controller_worker", + "description": "Worker for cloud controller asynchronous tasks", + "instances": "", + "instances_best_fit": 0, + "instance_type_id": "", + "instance_type_best_fit": "micro", + }, + { + "identifier": "diego_cell", + "description": "Diego Cell", + "instances": "", + "instances_best_fit": 0, + "instance_type_id": "medium", + "instance_type_best_fit": "xlarge.disk", + }, +]} diff --git a/cloud-foundry/polices/pshelpers/compare_numbers.rego b/cloud-foundry/polices/pshelpers/compare_numbers.rego index f0071c82..4ec45245 100644 --- a/cloud-foundry/polices/pshelpers/compare_numbers.rego +++ b/cloud-foundry/polices/pshelpers/compare_numbers.rego @@ -1,10 +1,8 @@ package pshelpers -isLimitExceeded(limit, set) = exceeded { - exceedsLimit := [ - aboveLimit | - set[_] > limit - aboveLimit := true - ] - exceeded = count(exceedsLimit) > 0 +import rego.v1 + +limit_exceeded(limit, set) if { + some item in set + item > limit } diff --git a/cloud-foundry/polices/pshelpers/compare_numbers_test.rego b/cloud-foundry/polices/pshelpers/compare_numbers_test.rego index 5afaa995..7029ef6e 100644 --- a/cloud-foundry/polices/pshelpers/compare_numbers_test.rego +++ b/cloud-foundry/polices/pshelpers/compare_numbers_test.rego @@ -1,25 +1,33 @@ -package pshelpers +package pshelpers_test -test_limit_equals { - limit = 20 - set = [10, 12, 15, 20] - false == isLimitExceeded(limit, set) +import rego.v1 + +import data.pshelpers + +test_limit_equals if { + limit := 20 + set := [10, 12, 15, 20] + + not pshelpers.limit_exceeded(limit, set) } -test_limit_is_exceeded { - limit = 20 - set = [10, 12, 15, 21] - true == isLimitExceeded(limit, set) +test_limit_is_exceeded if { + limit := 20 + set := [10, 12, 15, 21] + + pshelpers.limit_exceeded(limit, set) } -test_limit_not_exceeded { - limit = 20 - set = [10, 12, 15] - false == isLimitExceeded(limit, set) +test_limit_not_exceeded if { + limit := 20 + set := [10, 12, 15] + + not pshelpers.limit_exceeded(limit, set) } -test_multiple_limits_exceeded { - limit = 20 - set = [21, 22, 1] - true == isLimitExceeded(limit, set) +test_multiple_limits_exceeded if { + limit := 20 + set := [21, 22, 1] + + pshelpers.limit_exceeded(limit, set) } diff --git a/cloud-foundry/polices/pshelpers/object_matchers.rego b/cloud-foundry/polices/pshelpers/object_matchers.rego index dbd3bdb7..da41e39a 100644 --- a/cloud-foundry/polices/pshelpers/object_matchers.rego +++ b/cloud-foundry/polices/pshelpers/object_matchers.rego @@ -1,9 +1,7 @@ package pshelpers -path_value_match(searchObject, searchPath, searchValue) = exists { - matches := [ foundPath | - walk(searchObject, [searchPath, searchValue]) - foundPath = searchPath - ] - exists = count(matches) > 0 +import rego.v1 + +path_value_match(search_object, search_path, search_value) if { + walk(search_object, [search_path, search_value]) } diff --git a/cloud-foundry/polices/pshelpers/object_matchers_test.rego b/cloud-foundry/polices/pshelpers/object_matchers_test.rego index 6085c920..71245e7d 100644 --- a/cloud-foundry/polices/pshelpers/object_matchers_test.rego +++ b/cloud-foundry/polices/pshelpers/object_matchers_test.rego @@ -1,29 +1,29 @@ -package pshelpers - -test_path_value_match_with_correct_path_value { - expected := true - inputObject = {"random": {"stuff": "moo" }} - path := ["random", "stuff"] - value := "moo" - actual := path_value_match(inputObject, path, value) - actual == expected +package pshelpers_test + +import rego.v1 + +import data.pshelpers + +test_path_value_match_with_correct_path_value if { + input_object = {"random": {"stuff": "moo"}} + path := ["random", "stuff"] + value := "moo" + + pshelpers.path_value_match(input_object, path, value) } +test_path_value_match_incorrect_path if { + input_object = {"random": {"stuff": "moo"}} + path := ["incorrect", "path"] + value := "moo" -test_path_value_match_incorrect_path { - expected := false - inputObject = {"random": {"stuff": "moo" }} - path := ["incorrect", "path"] - value := "moo" - actual := path_value_match(inputObject, path, value) - actual == expected + not pshelpers.path_value_match(input_object, path, value) } -test_path_value_match_incorrect_value { - expected := false - inputObject = {"random": {"stuff": "moo" }} - path := ["random", "stuff"] - value := "incorrect" - actual := path_value_match(inputObject, path, value) - actual == expected +test_path_value_match_incorrect_value if { + input_object = {"random": {"stuff": "moo"}} + path := ["random", "stuff"] + value := "incorrect" + + not pshelpers.path_value_match(input_object, path, value) } diff --git a/cobertura/example/policy.rego b/cobertura/example/policy.rego index 24732cd0..a995b393 100644 --- a/cobertura/example/policy.rego +++ b/cobertura/example/policy.rego @@ -1,9 +1,11 @@ package policy -deny["foo"] { - input.foo == "bar" +import rego.v1 + +deny contains "foo" if { + input.foo == "bar" } -deny["bar"] { - input.bar == "foo" +deny contains "bar" if { + input.bar == "foo" } diff --git a/cobertura/example/policy_test.rego b/cobertura/example/policy_test.rego index 83f63d7a..f752c25e 100644 --- a/cobertura/example/policy_test.rego +++ b/cobertura/example/policy_test.rego @@ -1,5 +1,9 @@ -package policy +package policy_test -test_deny { - deny with input as {"foo": "bar"} +import rego.v1 + +import data.policy + +test_deny if { + policy.deny with input as {"foo": "bar"} } diff --git a/custom_bundle_signing/go.mod b/custom_bundle_signing/go.mod index bc5d1036..78dcd9f3 100644 --- a/custom_bundle_signing/go.mod +++ b/custom_bundle_signing/go.mod @@ -3,80 +3,101 @@ module github.com/open-policy-agent/contrib/custom_bundle_signing go 1.21 require ( - github.com/open-policy-agent/opa v0.55.0 - github.com/spf13/cobra v1.7.0 + github.com/open-policy-agent/opa v0.67.0 + github.com/spf13/cobra v1.8.1 ) require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/Microsoft/hcsshim v0.11.7 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/containerd/containerd v1.7.11 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/containerd/containerd v1.7.20 // indirect + github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect github.com/dgraph-io/badger/v3 v3.2103.5 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.1.0 // indirect + github.com/golang/glog v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/flatbuffers v1.12.1 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/mux v1.8.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/klauspost/compress v1.16.0 // indirect + github.com/klauspost/compress v1.17.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/locker v1.0.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/peterh/liner v1.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sergi/go-diff v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.18.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/sdk v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.uber.org/atomic v1.9.0 // indirect go.uber.org/automaxprocs v1.5.3 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/grpc v1.58.3 // indirect - google.golang.org/protobuf v1.33.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - oras.land/oras-go/v2 v2.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + oras.land/oras-go/v2 v2.3.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/custom_bundle_signing/go.sum b/custom_bundle_signing/go.sum index 6012e254..a1e4d58f 100644 --- a/custom_bundle_signing/go.sum +++ b/custom_bundle_signing/go.sum @@ -6,6 +6,7 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= @@ -20,27 +21,38 @@ github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HV github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= +github.com/containerd/containerd v1.7.20 h1:Sl6jQYk3TRavaU83h66QMbI2Nqg9Jm6qzwX57Vsn1SQ= +github.com/containerd/containerd v1.7.20/go.mod h1:52GsS5CwquuqPuLncsXwG0t2CiUce+KsNHJZQJvAgR0= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -61,6 +73,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= @@ -68,6 +82,8 @@ github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtV github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= @@ -75,6 +91,8 @@ github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= @@ -84,6 +102,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -103,6 +123,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -119,10 +141,17 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -132,6 +161,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -140,6 +171,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -149,6 +182,8 @@ github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= @@ -157,11 +192,18 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/open-policy-agent/opa v0.55.0 h1:s7Vm4ph6zDqqP/KzvUSw9fsKVsm9lhbTZhYGxxTK7mo= github.com/open-policy-agent/opa v0.55.0/go.mod h1:2Vh8fj/bXCqSwGMbBiHGrw+O8yrho6T/fdaHt5ROmaQ= +github.com/open-policy-agent/opa v0.67.0 h1:FOdsO9yNhfmrh+72oVK7ImWmzruG+VSpfbr5IBqEWVs= +github.com/open-policy-agent/opa v0.67.0/go.mod h1:aqKlHc8E2VAAylYE9x09zJYr/fYzGX+JKne89UGqFzk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw= github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -172,38 +214,63 @@ github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -211,6 +278,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -228,29 +297,51 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -269,6 +360,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -279,6 +372,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -291,12 +386,18 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -321,8 +422,12 @@ google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWo google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -331,6 +436,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -344,10 +451,14 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -358,3 +469,7 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= oras.land/oras-go/v2 v2.2.1 h1:3VJTYqy5KfelEF9c2jo1MLSpr+TM3mX8K42wzZcd6qE= oras.land/oras-go/v2 v2.2.1/go.mod h1:GeAwLuC4G/JpNwkd+bSZ6SkDMGaaYglt6YK2WvZP7uQ= +oras.land/oras-go/v2 v2.3.1 h1:lUC6q8RkeRReANEERLfH86iwGn55lbSWP20egdFHVec= +oras.land/oras-go/v2 v2.3.1/go.mod h1:5AQXVEu1X/FKp1F9DMOb5ZItZBOa0y5dha0yCm4NR9c= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/custom_bundle_signing/policy/awesome.rego b/custom_bundle_signing/policy/awesome.rego index f0314671..2a9a7b2f 100644 --- a/custom_bundle_signing/policy/awesome.rego +++ b/custom_bundle_signing/policy/awesome.rego @@ -1,7 +1,11 @@ package awesome -default awesome = false +import rego.v1 -awesome { +# regal ignore:rule-name-repeats-package +default awesome := false + +# regal ignore:rule-name-repeats-package +awesome if { input.awesome } diff --git a/dart_authz/policies/example.rego b/dart_authz/policies/example.rego index 739ee0b7..b12da376 100644 --- a/dart_authz/policies/example.rego +++ b/dart_authz/policies/example.rego @@ -1,62 +1,58 @@ package system -main = allow +import rego.v1 -default allow = false +# regal ignore:pointless-reassignment +main := allow -allow { +default allow := false + +allow if { input.method = "GET" - input.path = [""] + input.path = [""] } -allow { +allow if { input.method = "GET" - input.path = ["cars"] - + input.path = ["cars"] } -allow { +allow if { input.method = "GET" input.path = ["cars", car_id] } -allow { +allow if { input.method = "PUT" input.path = ["cars", car_id] - has_role("manager") + has_role("manager") } -allow { +allow if { input.method = "DELETE" input.path = ["cars", car_id] has_role("manager") } -allow { +allow if { input.method = "GET" input.path = ["cars", car_id, "status"] - employees[input.user] + employees[input.user] } -allow { +allow if { input.method = "PUT" input.path = ["cars", car_id, "status"] - has_role("car_admin") + has_role("car_admin") } -has_role(name) { - employee := employees[input.user] - employee.roles[name] +has_role(name) if { + employee := employees[input.user] # regal ignore:external-reference + employee.roles[name] } -employees = { - "alice": { - "roles": {"manager", "car_admin"}, - }, - "james": { - "roles": {"manager"}, - }, - "kelly": { - "roles": {"car_admin"}, - }, +employees := { + "alice": {"roles": {"manager", "car_admin"}}, + "james": {"roles": {"manager"}}, + "kelly": {"roles": {"car_admin"}}, } diff --git a/data_filter_azure/example_documentdb.rego b/data_filter_azure/example_documentdb.rego index 56f341c8..b05e5ad5 100644 --- a/data_filter_azure/example_documentdb.rego +++ b/data_filter_azure/example_documentdb.rego @@ -1,43 +1,63 @@ package documentdb.example -default allow = false - -allow { - allowed[_] -} - -allowed[user] { - data.permissions[user] - user.registry == input.registry - user.user == input.user - user.map[_].type == input.type - user.map[_].name == input.resourceName - contains(user.map[_].actions, input.action) -} - -allowed[user] { - data.permissions[user] - user.registry == input.registry - user.user == input.user - user.map[_].type == input.type - user.map[_].name == "*" - contains(user.map[_].actions, input.action) -} - -allowed[user] { - data.permissions[user] - user.registry == input.registry - user.user == input.user - user.map[_].type == input.type - user.map[_].name == input.resourceName - contains(user.map[_].actions, "*") -} - -allowed[user] { - data.permissions[user] - user.registry == input.registry - user.user == input.user - user.map[_].type == input.type - user.map[_].name == "*" - contains(user.map[_].actions, "*") -} \ No newline at end of file +import rego.v1 + +default allow := false + +allow if { + count(allowed) > 0 +} + +allowed contains user if { + some user, _ in data.permissions + user.registry == input.registry + user.user == input.user + type_in_input + matched_name + contains(user.map[_].actions, input.action) +} + +allowed contains user if { + some user, _ in data.permissions + user.registry == input.registry + user.user == input.user + type_in_input + wildcard_name + contains(user.map[_].actions, input.action) +} + +allowed contains user if { + some user, _ in data.permissions + user.registry == input.registry + user.user == input.user + type_in_input + matched_name + contains(user.map[_].actions, "*") +} + +allowed contains user if { + some user, _ in data.permissions + user.registry == input.registry + user.user == input.user + type_in_input + wildcard_name + contains(user.map[_].actions, "*") +} + +type_in_input if { + some user, _ in data.permissions + some map in user.map + map.type == input.type +} + +wildcard_name if { + some user, _ in data.permissions + some map in user.map + map.name == "*" +} + +matched_name if { + some user, _ in data.permissions + some map in user.map + map.name == input.resourceName +} diff --git a/data_filter_azure/example_tablestorage.rego b/data_filter_azure/example_tablestorage.rego index 2421d609..4c4dd9da 100644 --- a/data_filter_azure/example_tablestorage.rego +++ b/data_filter_azure/example_tablestorage.rego @@ -1,19 +1,21 @@ package example -default allow = false +import rego.v1 -allow { - input.data[input.type][input.resourceName].actions[_] == input.action +default allow := false + +allow if { + input.action in input.data[input.type][input.resourceName].actions } -allow { - input.data[input.type][input.resourceName].actions[_] == "*" +allow if { + "*" in input.data[input.type][input.resourceName].actions } -allow { - input.data[input.type]["*"].actions[_] == input.action +allow if { + input.action in input.data[input.type]["*"].actions } -allow { - input.data[input.type]["*"].actions[_] == "*" +allow if { + "*" in input.data[input.type]["*"].actions } diff --git a/data_filter_elasticsearch/example-conditions.rego b/data_filter_elasticsearch/example-conditions.rego index 7a567ca9..0b8c06be 100644 --- a/data_filter_elasticsearch/example-conditions.rego +++ b/data_filter_elasticsearch/example-conditions.rego @@ -1,94 +1,87 @@ package example -policies = [ - { - "subjects": [ - "group:users" - ], - "resource": [ - "posts" - ], - "action": "GET", - "condition": [ - { - "field": "author", - "ref": "user", - "operator": "equal" - }, - { - "field": "id", - "value": "post1", - "operator": "equal" - } - ] - }, - { - "subjects": [ - "group:admin" - ], - "resource": [ - "posts" - ], - "action": "GET", - "condition": [ - { - "field": "clearance", - "ref": "level", - "value": 9, - "operator": "greater_than" - } - ] - } +import rego.v1 + +policies := [ + { + "subjects": ["group:users"], + "resource": ["posts"], + "action": "GET", + "condition": [ + { + "field": "author", + "ref": "user", + "operator": "equal", + }, + { + "field": "id", + "value": "post1", + "operator": "equal", + }, + ], + }, + { + "subjects": ["group:admin"], + "resource": ["posts"], + "action": "GET", + "condition": [{ + "field": "clearance", + "ref": "level", + "value": 9, + "operator": "greater_than", + }], + }, ] ### Entry point to the policy. ### Example with conditions being interpreted. -allow { - p := policies[_] - p.action = input.method - p.resource = input.path - r := data.elastic[p.resource[0]][_] - all_conditions_true(p, r) +allow if { + some p in policies + p.action = input.method + p.resource = input.path + some r in data.elastic[p.resource[0]] + all_conditions_true(p, r) } -all_conditions_true(p, r) { - not any_condition_false(p, r) + +all_conditions_true(p, r) if { + not any_condition_false(p, r) } -any_condition_false(p, r) { - c := p.condition[_] - not eval(r, c.operator, c) + +any_condition_false(p, r) if { + some c in p.condition + not eval(r, c.operator, c) } ### Equality operator # OPA Query: "bob" = data.elastic.posts[_].author; "post1" = data.elastic.posts[_].id # ES Query: {name:author value:bob boost: queryName:TermQuery} -eval(r, "equal", c) { - r[c.field] = input[c.ref] +eval(r, "equal", c) if { + r[c.field] == input[c.ref] # regal ignore:external-reference } # OPA Query: "bob" = data.elastic.posts[_].author; "post1" = data.elastic.posts[_].id # ES Query: {name:id value:post1 boost: queryName:TermQuery} -eval(r, "equal", c) { - r[c.field] = c.value +eval(r, "equal", c) if { + r[c.field] == c.value } ### Greater Than operator # OPA Query: gt(data.elastic.posts[_].clearance, 9) -# ES Query: {name:clearance from:9 to: timeZone: includeLower:false includeUpper:true boost: queryName: format: relation:} -eval(r, "greater_than", c) { - r[c.field] > c.value +# ES Query: {name:clearance from:9 to: timeZone: includeLower:false +# includeUpper:true boost: queryName: format: relation:} +eval(r, "greater_than", c) if { + r[c.field] > c.value } - ### Sample Input to OPA. # { # "method": "GET", # "path": ["posts"], # "user": "bob" # } - ### Sample Output from Elasticsearch. # { # "result": [ @@ -135,4 +128,4 @@ eval(r, "greater_than", c) { # "stats": [] # } # ] -# } \ No newline at end of file +# } diff --git a/data_filter_elasticsearch/policy/example.rego b/data_filter_elasticsearch/policy/example.rego index e8fa3804..8a96d848 100644 --- a/data_filter_elasticsearch/policy/example.rego +++ b/data_filter_elasticsearch/policy/example.rego @@ -1,21 +1,23 @@ package example +import rego.v1 + ### Entry point to the policy. ### Matches on incoming request. # Rule matching collection of posts. -allow = true { - input.method = "GET" - input.path = ["posts"] - allowed[x] +allow if { + input.method == "GET" + input.path == ["posts"] + count(allowed) > 0 } # Rule matching individual post. -allow = true { - input.method = "GET" - input.path = ["posts", post_id] - allowed[x] - x.id = post_id +allow if { + input.method = "GET" + input.path = ["posts", post_id] + some x in allowed + x.id = post_id } ### Helper rules that implement data filtering & protection policy. @@ -59,9 +61,9 @@ allow = true { # } # ] # } -allowed[x] { - x := data.elastic.posts[_] - x.author == input.user +allowed contains x if { + some x in data.elastic.posts + x.author == input.user } ### Simple built-in functions like !=, >, <. @@ -69,10 +71,14 @@ allowed[x] { # Return posts with clearance level greater than 0 and less than equal to 5 # but no posts from "it". -# OPA Query: lte(data.elastic.posts[_].clearance, 5); gt(data.elastic.posts[_].clearance, 0); neq(data.elastic.posts[_].department, "it") -# ES Query 1: {name:clearance from: to:5 timeZone: includeLower:true includeUpper:true boost: queryName: format: relation:} -# ES Query 2: {name:clearance from:0 to: timeZone: includeLower:false includeUpper:true boost: queryName: format: relation:} -# ES Query 3: {Query: mustClauses:[] mustNotClauses:[0xc0002ae240] filterClauses:[] shouldClauses:[] boost: minimumShouldMatch: adjustPureNegative: queryName:BoolMustNotQuery} +# OPA Query: lte(data.elastic.posts[_].clearance, 5); gt(data.elastic.posts[_].clearance, 0); +# neq(data.elastic.posts[_].department, "it") +# ES Query 1: {name:clearance from: to:5 timeZone: includeLower:true +# includeUpper:true boost: queryName: format: relation:} +# ES Query 2: {name:clearance from:0 to: timeZone: includeLower:false +# includeUpper:true boost: queryName: format: relation:} +# ES Query 3: {Query: mustClauses:[] mustNotClauses:[0xc0002ae240] filterClauses:[] +# shouldClauses:[] boost: minimumShouldMatch: adjustPureNegative: queryName:BoolMustNotQuery} # Sample Output from Elasticsearch: # { # "result": [ @@ -134,11 +140,11 @@ allowed[x] { # } # ] # } -allowed[x] { - x := data.elastic.posts[_] - x.clearance <= 5 - x.clearance > 0 - x.department != "it" +allowed contains x if { + some x in data.elastic.posts + x.clearance <= 5 + x.clearance > 0 + x.department != "it" } ### Built-in functions like string contains and regexp. @@ -146,9 +152,12 @@ allowed[x] { # Return posts containing the term "OPA" in their message. # OPA Query: contains(data.elastic.posts[_].message, "OPA") -# ES Query: {queryString:*OPA* defaultField:message defaultOperator: analyzer: quoteAnalyzer: quoteFieldSuffix: allowLeadingWildcard: lowercaseExpandedTerms: -# enablePositionIncrements: analyzeWildcard: locale: boost: fuzziness: fuzzyPrefixLength: fuzzyMaxExpansions: fuzzyRewrite: phraseSlop: -# fields:[] fieldBoosts:map[] tieBreaker: rewrite: minimumShouldMatch: lenient: queryName:QueryStringQuery timeZone: maxDeterminizedStates: escape: typ:} +# ES Query: {queryString:*OPA* defaultField:message defaultOperator: analyzer: quoteAnalyzer: +# quoteFieldSuffix: allowLeadingWildcard: lowercaseExpandedTerms: +# enablePositionIncrements: analyzeWildcard: locale: boost: fuzziness: +# fuzzyPrefixLength: fuzzyMaxExpansions: fuzzyRewrite: phraseSlop: +# fields:[] fieldBoosts:map[] tieBreaker: rewrite: minimumShouldMatch: lenient: +# queryName:QueryStringQuery timeZone: maxDeterminizedStates: escape: typ:} # Sample Output from Elasticsearch: # { # "result": [ @@ -182,15 +191,16 @@ allowed[x] { # } # ] # } -allowed[x] { - x := data.elastic.posts[_] - contains(x.message, "OPA") +allowed contains x if { + some x in data.elastic.posts + contains(x.message, "OPA") } # Return posts who email address matches the ".org" domain. # OPA Query: re_match("[a-zA-Z]+@[a-zA-Z]+.org", data.elastic.posts[_].email) -# ES Query: {name:email regexp:[a-zA-Z]+@[a-zA-Z]+.org flags: boost: rewrite: queryName: maxDeterminizedStates:} +# ES Query: {name:email regexp:[a-zA-Z]+@[a-zA-Z]+.org flags: boost: rewrite: +# queryName: maxDeterminizedStates:} # Sample Output from Elasticsearch: # { # "result": [ @@ -210,9 +220,9 @@ allowed[x] { # } # ] # } -allowed[x] { - x := data.elastic.posts[_] - re_match("[a-zA-Z]+@[a-zA-Z]+.org", x.email) +allowed contains x if { + some x in data.elastic.posts + regex.match(`[a-zA-Z]+@[a-zA-Z]+.org`, x.email) } ### Nested examples which include a search. @@ -220,7 +230,8 @@ allowed[x] { # Return posts liked by input.user. # OPA Query: "bob" = data.elastic.posts[_].likes[_].name -# ES Query: {query:0xc00032a800 path:likes scoreMode: boost: queryName:NestedQuery innerHit: ignoreUnmapped:0xc0004985f8} +# ES Query: {query:0xc00032a800 path:likes scoreMode: boost: queryName:NestedQuery innerHit: +# ignoreUnmapped:0xc0004985f8} # Sample Output from Elasticsearch: # { # "result": [ @@ -244,16 +255,17 @@ allowed[x] { # } # ] # } -allowed[x] { - x := data.elastic.posts[_] - y := x.likes[_] - y.name = input.user +allowed contains x if { + some x in data.elastic.posts + some y in x.likes + y.name = input.user } # Return posts followed by input.user. # OPA Query: "bob" = data.elastic.posts[_].followers[_].info.first -# ES Query: {query:0xc0001f0b40 path:followers.info scoreMode: boost: queryName:NestedQuery innerHit: ignoreUnmapped:0xc00038a67c} +# ES Query: {query:0xc0001f0b40 path:followers.info scoreMode: boost: queryName:NestedQuery innerHit: +# ignoreUnmapped:0xc00038a67c} # Sample Output from Elasticsearch: # { # "result": [ @@ -280,10 +292,10 @@ allowed[x] { # } # ] # } -allowed[x] { - x := data.elastic.posts[_] - y := x.followers[_] - y.info.first = input.user +allowed contains x if { + some x in data.elastic.posts + some y in x.followers + y.info.first == input.user } ### Deeply nested example. @@ -291,7 +303,8 @@ allowed[x] { # Return posts by authors from CA. # OPA Query: data.elastic.posts[_].stats[_].authorstat.authorbio.state = "CA" -# ES Query: {query:0xc0004edd40 path:stats.authorstat.authorbio scoreMode: boost: queryName:NestedQuery innerHit: ignoreUnmapped:0xc0004f1471} +# ES Query: {query:0xc0004edd40 path:stats.authorstat.authorbio scoreMode: boost: queryName:NestedQuery +# innerHit: ignoreUnmapped:0xc0004f1471} # Sample Output from Elasticsearch: # { # "result": [ @@ -321,8 +334,8 @@ allowed[x] { # } # ] # } -allowed[x] { - x := data.elastic.posts[_] - y := x.stats[_] - y.authorstat.authorbio.state = "CA" +allowed contains x if { + some x in data.elastic.posts + some y in x.stats + y.authorstat.authorbio.state == "CA" } diff --git a/data_filter_example/example.rego b/data_filter_example/example.rego index 219bcd33..43201b9e 100644 --- a/data_filter_example/example.rego +++ b/data_filter_example/example.rego @@ -1,40 +1,44 @@ package example +import rego.v1 + # data.example.allow == true # # {"input": {"method": "GET", "path": ...}, "unknowns": ["data.posts"]} -allow { - input.method = "POST" - input.path = ["posts"] - input.subject.user # authenticated users can create posts +allow if { + input.method == "POST" + input.path == ["posts"] + input.subject.user # authenticated users can create posts } -allow { - input.method = "GET" - input.path = ["posts", post_id] - allowed[post] - post.id = post_id +allow if { + some post_id + input.method == "GET" + input.path = ["posts", post_id] + + some post in allowed + post.id == post_id } -allow { - input.method = "GET" - input.path = ["posts"] - allowed[_] +allow if { + input.method == "GET" + input.path == ["posts"] + count(allowed) > 0 } -allowed[post] { - data.posts[post] - post.author = input.subject.user +allowed contains post if { + some post in data.posts + post.author == input.subject.user } -allowed[post] { - data.posts[post] - post.department = input.subject.departments[_] - post.clearance_level <= input.subject.clearance_level +allowed contains post if { + some post in data.posts + post.department in input.subject.departments + post.clearance_level <= input.subject.clearance_level } -allowed[post] { - data.posts[post] - post.department = "company" +allowed contains post if { + some post in data.posts + post.department == "company" } diff --git a/data_filter_mongodb/example.rego b/data_filter_mongodb/example.rego index 666a50d7..69ac2a6f 100644 --- a/data_filter_mongodb/example.rego +++ b/data_filter_mongodb/example.rego @@ -1,25 +1,26 @@ package details.authz -allow { - input.method == "GET" - employee := data.employees[_] - employee.name == input.user - employee.name == input.path[1] -} +import rego.v1 -allow { - input.method == "GET" - employee := data.employees[_] - employee.manager == input.user - employee.name == input.path[1] +allow if { + input.method == "GET" + some employee in data.employees + employee.name == input.user + employee.name == input.path[1] } -allow { - input.method == "GET" - input.path = ["employees"] - employee := data.employees[_] - input.user == "danerys" - employee.salary > 0 - employee.salary < 300000 +allow if { + input.method == "GET" + some employee in data.employees + employee.manager == input.user + employee.name == input.path[1] } +allow if { + input.method == "GET" + input.path = ["employees"] + some employee in data.employees + input.user == "danerys" + employee.salary > 0 + employee.salary < 300000 +} diff --git a/image_enforcer/policies/default.rego b/image_enforcer/policies/default.rego index b93aa240..f483e846 100644 --- a/image_enforcer/policies/default.rego +++ b/image_enforcer/policies/default.rego @@ -3,19 +3,18 @@ # The default policy will not reject any images unless they have been blacklisted. # By default, the blacklist is empty. - package io.k8s.image_policy -verify = { - "apiVersion": "imagepolicy.k8s.io/v1alpha1", - "kind": "ImageReview", - "status": { - "allowed": allow, - }, +import rego.v1 + +verify := { + "apiVersion": "imagepolicy.k8s.io/v1alpha1", + "kind": "ImageReview", + "status": {"allowed": allow}, } -default allow = false +default allow := false -allow { not deny } +allow if not deny -default deny = false +default deny := false diff --git a/image_enforcer/policies/mock/input.rego b/image_enforcer/policies/mock/input.rego index 03a94b08..c22e54d7 100644 --- a/image_enforcer/policies/mock/input.rego +++ b/image_enforcer/policies/mock/input.rego @@ -2,32 +2,25 @@ package mock -allowed = { - "kind": "ImageReview", - "apiVersion": "imagepolicy.k8s.io/v1alpha1", - "spec": { - "containers": [ - { - "image": "openpolicyagent/opa:0.4.9" - } - ], - "namespace": "production" - } -} +import rego.v1 +allowed := { + "kind": "ImageReview", + "apiVersion": "imagepolicy.k8s.io/v1alpha1", + "spec": { + "containers": [{"image": "openpolicyagent/opa:0.4.9"}], + "namespace": "production", + }, +} -denied = { - "kind": "ImageReview", - "apiVersion": "imagepolicy.k8s.io/v1alpha1", - "spec": { - "containers": [ - { - "image": "openpolicyagent/opa:0.4.9" - }, - { - "image": "library/wordpress:4-apache" - } - ], - "namespace": "production" - } +denied := { + "kind": "ImageReview", + "apiVersion": "imagepolicy.k8s.io/v1alpha1", + "spec": { + "containers": [ + {"image": "openpolicyagent/opa:0.4.9"}, + {"image": "library/wordpress:4-apache"}, + ], + "namespace": "production", + }, } diff --git a/image_enforcer/policies/scan.rego b/image_enforcer/policies/scan.rego index 99306f79..ef023c05 100644 --- a/image_enforcer/policies/scan.rego +++ b/image_enforcer/policies/scan.rego @@ -2,24 +2,25 @@ package io.k8s.image_policy -secure_namespaces = { - "production", -} +import rego.v1 + +secure_namespaces := {"production"} -deny { - secure_namespaces[input.spec.namespace] - image_layers[tuple] - tuple = [org, name, tag, layer] - vulnerable_layers[layer] +deny if { + input.spec.namespace in secure_namespaces + some tuple in image_layers + some [org, name, tag, layer] in tuple + layer in vulnerable_layers } -image_layers[[org, name, tag, layer]] { - input.spec.containers[i].image = img - split(img, ":", [repo, tag]) - split(repo, "/", [org, name]) - data.docker.layers[org][name][tag].layers[_].digest = layer +image_layers contains [org, name, tag, layer.digest] if { + some container in input.spec.containers + [repo, tag] := split(container.image, ":") + [org, name] := split(repo, "/") + some layer in data.docker.layers[org][name][tag].layers } -vulnerable_layers[layer] { - data.clair.layers[layer].Layer.Features[_].Vulnerabilities != [] +vulnerable_layers contains layer if { + some layer + data.clair.layers[layer].Layer.Features[_].Vulnerabilities != [] # regal ignore:not-equals-in-loop } diff --git a/k8s_api_client/policy/api_client.rego b/k8s_api_client/policy/api_client.rego index 43ab79f9..dc100840 100644 --- a/k8s_api_client/policy/api_client.rego +++ b/k8s_api_client/policy/api_client.rego @@ -1,5 +1,7 @@ package kubernetes.api.client +import rego.v1 + # This information could be retrieved from the kubernetes API # too, but would essentially require a request per API group, # so for now use a lookup table for the most common resources. @@ -22,8 +24,9 @@ resource_group_mapping := { # Query for given resource/name in provided namespace # Example: query_ns("deployments", "my-app", "default") -query_name_ns(resource, name, namespace) = http.send({ +query_name_ns(resource, name, namespace) := http.send({ "url": sprintf("https://kubernetes.default.svc/%v/namespaces/%v/%v/%v", [ + # regal ignore:external-reference resource_group_mapping[resource], namespace, resource, @@ -38,8 +41,9 @@ query_name_ns(resource, name, namespace) = http.send({ # Query for given resource type using label selectors # https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api # Example: query_label_selector_ns("deployments", {"app": "opa-kubernetes-api-client"}, "default") -query_label_selector_ns(resource, selector, namespace) = http.send({ +query_label_selector_ns(resource, selector, namespace) := http.send({ "url": sprintf("https://kubernetes.default.svc/%v/namespaces/%v/%v?labelSelector=%v", [ + # regal ignore:external-reference resource_group_mapping[resource], namespace, resource, @@ -53,8 +57,9 @@ query_label_selector_ns(resource, selector, namespace) = http.send({ # Query for all resources of type resource in all namespaces # Example: query_all("deployments") -query_all(resource) = http.send({ +query_all(resource) := http.send({ "url": sprintf("https://kubernetes.default.svc/%v/%v", [ + # regal ignore:external-reference resource_group_mapping[resource], resource, ]), @@ -64,4 +69,4 @@ query_all(resource) = http.send({ "raise_error": false, }) -label_map_to_query_string(map) = concat(",", [str | val := map[key]; str := concat("%3D", [key, val])]) +label_map_to_query_string(map) := concat(",", [str | val := map[key]; str := concat("%3D", [key, val])]) diff --git a/k8s_authorization/policy/policy.rego b/k8s_authorization/policy/policy.rego index 3ac890c6..863751ea 100644 --- a/k8s_authorization/policy/policy.rego +++ b/k8s_authorization/policy/policy.rego @@ -1,16 +1,18 @@ package k8s.authz -deny[reason] { +import rego.v1 + +deny contains reason if { input.spec.resourceAttributes.namespace == "kube-system" reason := "OPA: denied access to namespace kube-system" } -deny[reason] { +deny contains reason if { input.spec.resourceAttributes.namespace == "opa" required_groups := {"system:authenticated", "devops"} - provided_groups := {group | group := input.spec[groups][_]} + provided_groups := {group | some group in input.spec[groups]} count(required_groups & provided_groups) != count(required_groups) @@ -20,7 +22,7 @@ deny[reason] { ]) } -decision = { +decision := { "apiVersion": input.apiVersion, "kind": "SubjectAccessReview", "status": { @@ -32,7 +34,7 @@ decision = { # Take into account the typo of missing "s" in groups # in v1beta1 version (which is used by default) # https://github.com/kubernetes/kubernetes/issues/32709 -groups = { +groups := { "authorization.k8s.io/v1": "groups", "authorization.k8s.io/v1beta1": "group", }[input.apiVersion] diff --git a/k8s_node_selector/authz.rego b/k8s_node_selector/authz.rego index 8936b8e8..1ec1393a 100644 --- a/k8s_node_selector/authz.rego +++ b/k8s_node_selector/authz.rego @@ -1,22 +1,24 @@ package system.authz +import rego.v1 + # Deny access by default. -default allow = false +default allow := false # Allow anonymous access to the default policy decision. -allow { - input.method = "POST" - input.path = [""] +allow if { + input.method == "POST" + input.path == [""] } - -# Allow anonymouse access to /health otherwise K8s get 403 and kills pod. -allow { - input.path = ["health"] +# Allow anonymouse access to /health otherwise K8s get 403 and kills pod. +allow if { + input.path == ["health"] } # Allow authenticated traffic from the kube-mgmt sidecar # in `./deploy.sh` the `{TOKEN_HERE}` variable is replaced -allow { - "{TOKEN_HERE}" = input.identity -} \ No newline at end of file + +allow if { + input.identity == "{TOKEN_HERE}" +} diff --git a/k8s_node_selector/data_input.rego b/k8s_node_selector/data_input.rego index 14b942fc..f9a4bad6 100644 --- a/k8s_node_selector/data_input.rego +++ b/k8s_node_selector/data_input.rego @@ -1,29 +1,23 @@ package node_selector.testdata -example_namespaces_with_label = { "default": { - "apiVersion": "v1", - "kind": "Namespace", - "metadata": { - "creationTimestamp": "2020-01-17T14:18:28Z", - "labels": { - "agentpool": "pool1", - }, - "name": "default", - "resourceVersion": "517", - "selfLink": "/api/v1/namespaces/kube-system", - "uid": "d20094e6-bdfb-4d7c-a887-a8fd99d9f3dc" - }, - "spec": { - "finalizers": [ - "kubernetes" - ] - }, - "status": { - "phase": "Active" - } +import rego.v1 + +example_namespaces_with_label := {"default": { + "apiVersion": "v1", + "kind": "Namespace", + "metadata": { + "creationTimestamp": "2020-01-17T14:18:28Z", + "labels": {"agentpool": "pool1"}, + "name": "default", + "resourceVersion": "517", + "selfLink": "/api/v1/namespaces/kube-system", + "uid": "d20094e6-bdfb-4d7c-a887-a8fd99d9f3dc", + }, + "spec": {"finalizers": ["kubernetes"]}, + "status": {"phase": "Active"}, }} -example_pod_has_node_selector = { +example_pod_has_node_selector := { "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "request": { @@ -42,9 +36,7 @@ example_pod_has_node_selector = { "uid": "bbfee96d-d98d-11e8-b280-080027868e77", }, "spec": { - "nodeSelector": { - "nodePool": "pool1" - }, + "nodeSelector": {"nodePool": "pool1"}, "containers": [{ "image": "nginx", "imagePullPolicy": "Always", @@ -107,7 +99,7 @@ example_pod_has_node_selector = { }, } -example_pod_has_nonexisting_namespace = { +example_pod_has_nonexisting_namespace := { "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "request": { @@ -188,8 +180,7 @@ example_pod_has_nonexisting_namespace = { }, } - -example_pod_doesnt_have_node_selector = { +example_pod_doesnt_have_node_selector := { "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "request": { diff --git a/k8s_node_selector/main.rego b/k8s_node_selector/main.rego index ca31bfc9..2b286633 100644 --- a/k8s_node_selector/main.rego +++ b/k8s_node_selector/main.rego @@ -1,9 +1,9 @@ package system -import data.kuberentes.namespaces +import rego.v1 # The top level response sent to the webrequest -main = { +main := { "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "response": response, @@ -11,82 +11,83 @@ main = { # If the conditions on the `response` below aren't met this default `allow` response # is returned. -default response = {"allowed": true } +default response := {"allowed": true} # These are the options for the response body sent back to admissions controller request # it starts with a number of conditions which have to be met for it to take effect -# -response = output { # -# Option 1: Return Allowed=false if -# - A Pod -# - In a namespace we care about -# - With nodeselector already specified <- Shouldn't be done for a namespace with a mapping - isPod - getPoolForNamespace(input.request.namespace) - hasNodeSelector +# regal ignore:rule-length +response := output if { + # + # Option 1: Return Allowed=false if + # - A Pod + # - In a namespace we care about + # - With nodeselector already specified <- Shouldn't be done for a namespace with a mapping + is_pod + pool_for_namespace(input.request.namespace) + has_node_selector - output := { - "allowed": false, - "status": { - "code": 403, - "reason": "Manually specifying NodeSelector not supported in this namespace." - } - } -} else = output { -# -# Option 2: Set the AgentPool=CorrectPool -# - A Pod -# - Without a nodeselector already specified -# - In a namespace we care about -# - Has a mapping set for the namespace - isPod - not hasNodeSelector + output := { + "allowed": false, + "status": { + "code": 403, + "reason": "Manually specifying NodeSelector not supported in this namespace.", + }, + } +} else := output if { + # + # Option 2: Set the AgentPool=CorrectPool + # - A Pod + # - Without a nodeselector already specified + # - In a namespace we care about + # - Has a mapping set for the namespace + is_pod + not has_node_selector + + # Generate the JSON Patch object + patch := { + "op": "add", + "path": "/spec/nodeSelector", + "value": {"agentpool": pool_for_namespace(input.request.namespace)}, + } - # Generate the JSON Patch object - patch := { - "op": "add", - "path": "/spec/nodeSelector", - "value": { - # Retrieve the `pool` name which should be applied given the - # namespace in which this pod is created. - "agentpool": getPoolForNamespace(input.request.namespace) - } - } + # Patches have to be an array of base64 encoded JSON Patches so lets + # make our single patch into an array, serialize as JSON and base64 encode. + patches := [patch] + patch_encoded := base64.encode(json.marshal(patches)) - # Patches have to be an array of base64 encoded JSON Patches so lets - # make our single patch into an array, serialize as JSON and base64 encode. - patches := [patch] - patchEncoded := base64.encode(json.marshal(patches)) - - # Output a trace use `opa test *.rego -v --explain full` to see them. - trace(sprintf("POLICY:generatedPatch raw = '%s'", [patches])) - trace(sprintf("POLICY:generatedPatch encoded = '%s'", [patchEncoded])) - + # Output a trace use `opa test *.rego -v --explain full` to see them. + trace(sprintf("POLICY:generatedPatch raw = '%s'", [patches])) # regal ignore:print-or-trace-call + trace(sprintf("POLICY:generatedPatch encoded = '%s'", [patch_encoded])) # regal ignore:print-or-trace-call - # Generate the patch response and return it! We're done! - output := { + # Generate the patch response and return it! We're done! + output := { "allowed": true, "patchType": "JSONPatch", - "patch": patchEncoded + "patch": patch_encoded, } } # Rule: Check if the item submitted is a pod. -isPod { - input.request.kind.kind == "Pod" +is_pod if { + input.request.kind.kind == "Pod" } # Rule: Check if pod already has a `nodeSelector` set -hasNodeSelector { - input.request.object.spec.nodeSelector - count(input.request.object.spec.nodeSelector) > 0 +has_node_selector if { + input.request.object.spec.nodeSelector + count(input.request.object.spec.nodeSelector) > 0 } -# Rule: For the given namespace get the `agentpool` label set -# on the namespace object itself -getPoolForNamespace(namespace) = poolLabel { - trace(sprintf("POLICY:namespace raw = '%s'", [data.kubernetes.namespaces])) - cluster_namespace := data.kubernetes.namespaces[namespace] - poolLabel = cluster_namespace.metadata.labels.agentpool -} \ No newline at end of file +# Rule: For the given namespace get the `agentpool` label set +# on the namespace object itself + +pool_for_namespace(namespace) := pool_label if { + # regal ignore:print-or-trace-call,external-reference + trace(sprintf("POLICY:namespace raw = '%s'", [data.kubernetes.namespaces])) + + # regal ignore:external-reference + cluster_namespace := data.kubernetes.namespaces[namespace] + + pool_label = cluster_namespace.metadata.labels.agentpool +} diff --git a/k8s_node_selector/node_selector_test.rego b/k8s_node_selector/node_selector_test.rego new file mode 100644 index 00000000..57d3cc19 --- /dev/null +++ b/k8s_node_selector/node_selector_test.rego @@ -0,0 +1,100 @@ +package system_test + +import rego.v1 + +import data.node_selector.testdata + +import data.system + +# ----------------------------------------------------------- +# Test: Test patch applied to pods +# ----------------------------------------------------------- + +# patch we expect to be generated +expected_patch := { + "op": "add", + "path": "/spec/nodeSelector", + "value": {"agentpool": "pool1"}, +} + +# Checks the response is a patch response +is_patch_response(res) if { + # Is the response patch type correct? + res.response.patchType == "JSONPatch" + + # Is the patch body set? + res.response.patch + + # Is the patch body an array with at least one item? + count(res.response.patch) > 0 +} + +# Test that the controller correctly sets a patch on a pod +# to assign it the correct `nodeSelector` of `agentpool=pool1` +# when in a namespace with label `agentpool=pool1` +test_response_patch_valid_mapping if { + # Invoke the policy main with a pod which doesn't have a node selector + # and is in the default namespace + body := system.main with input as testdata.example_pod_doesnt_have_node_selector + with data.kubernetes.namespaces as testdata.example_namespaces_with_label + + # Check policy returned an allowed response + body.response.allowed == true + + # Check the response is a patch response + is_patch_response(body) + + # The admission controller response is an array of base64 encoded + # jsonpatches so deserialize so we can review them. + patches := json.unmarshal(base64.decode(body.response.patch)) + + # Output some tracing... `opa test *.rego -v --explain full` to see them + trace(sprintf("TEST:appliedPatch = '%s'", [patches])) # regal ignore:print-or-trace-call + trace(sprintf("TEST:expectedPatch = '%s'", [expected_patch])) # regal ignore:print-or-trace-call + + # Check the policy created the expected patch + expected_patch in patches +} + +# Test that the controller accepts a pod in a namespace without an agent pool mapping +test_response_patch_invalid_mapping if { + # Invoke the policy main with a pod which doesn't have a node selector + # and is in the default namespace + body := system.main with input as testdata.example_pod_has_nonexisting_namespace + with data.kubernetes.namespaces as testdata.example_namespaces_with_label + + # Check policy returned an allowed response + body.response.allowed == true +} + +# Test that the controller rejects a pod with a nodeselector already set +test_response_patch_valid_mapping_with_nodeselector if { + # Invoke the policy main with a pod which doesn't have a node selector + # and is in the default namespace + body := system.main with input as testdata.example_pod_has_node_selector + with data.kubernetes.namespaces as testdata.example_namespaces_with_label + + # Check policy returned an allowed response + body.response.allowed == false +} + +# ----------------------------------------------------------- +# Helpers: Test helper functions used by the policy +# ----------------------------------------------------------- + +test_has_selector_has_selector if { + system.has_node_selector with input as testdata.example_pod_has_node_selector +} + +test_has_selector_doesnt_have_selector if { + not system.has_node_selector with input as testdata.example_pod_doesnt_have_node_selector +} + +test_response_allowed if { + body := system.main with input as testdata.example_pod_doesnt_have_node_selector + body.response.allowed == true +} + +test_is_pod_true if { + system.is_pod with input as testdata.example_pod_has_node_selector +} diff --git a/k8s_node_selector/test_node_selector.rego b/k8s_node_selector/test_node_selector.rego deleted file mode 100644 index 76c6a801..00000000 --- a/k8s_node_selector/test_node_selector.rego +++ /dev/null @@ -1,106 +0,0 @@ -package system - -import data.node_selector.testdata as testdata - -#----------------------------------------------------------- -# Test: Test patch applied to pods -#----------------------------------------------------------- - -# patch we expect to be generated -expectedPatch = { - "op": "add", - "path": "/spec/nodeSelector", - "value": { - "agentpool": "pool1", - } -} - -# Helper to check patch is set -hasPatch(patches, expectedPatch) { - # One of the patches returned should match the `expectedPatch` - patches[i] == expectedPatch -} - -# Checks the response is a patch response -isPatchResponse(res) { - # Is the response patch type correct? - res.response.patchType == "JSONPatch" - # Is the patch body set? - res.response.patch - # Is the patch body an array with at least one item? - count(res.response.patch) > 0 -} - -# Test that the controller correctly sets a patch on a pod -# to assign it the correct `nodeSelector` of `agentpool=pool1` -# when in a namespace with label `agentpool=pool1` -test_response_patch_valid_mapping { - # Invoke the policy main with a pod which doesn't have a node selector - # and is in the default namespace - body := main - with input as testdata.example_pod_doesnt_have_node_selector - with data.kubernetes.namespaces as testdata.example_namespaces_with_label - - # Check policy returned an allowed response - body.response.allowed == true - - # Check the response is a patch response - isPatchResponse(body) - - # The admission controller response is an array of base64 encoded - # jsonpatches so deserialize so we can review them. - patches := json.unmarshal(base64.decode(body.response.patch)) - - # Output some tracing... `opa test *.rego -v --explain full` to see them - trace(sprintf("TEST:appliedPatch = '%s'", [patches])) - trace(sprintf("TEST:expectedPatch = '%s'", [expectedPatch])) - - # Check the policy created the expected patch - hasPatch(patches, expectedPatch) -} - - -# Test that the controller accepts a pod in a namespace without an agent pool mapping -test_response_patch_invalid_mapping { - # Invoke the policy main with a pod which doesn't have a node selector - # and is in the default namespace - body := main - with input as testdata.example_pod_has_nonexisting_namespace - with data.kubernetes.namespaces as testdata.example_namespaces_with_label - - # Check policy returned an allowed response - body.response.allowed == true -} - -# Test that the controller rejects a pod with a nodeselector already set -test_response_patch_valid_mapping_with_nodeselector { - # Invoke the policy main with a pod which doesn't have a node selector - # and is in the default namespace - body := main - with input as testdata.example_pod_has_node_selector - with data.kubernetes.namespaces as testdata.example_namespaces_with_label - - # Check policy returned an allowed response - body.response.allowed == false -} - -#----------------------------------------------------------- -# Helpers: Test helper functions used by the policy -#----------------------------------------------------------- - -test_hasSelector_has_selector { - hasNodeSelector with input as testdata.example_pod_has_node_selector -} - -test_hasSelector_doesnt_have_selector { - not hasNodeSelector with input as testdata.example_pod_doesnt_have_node_selector -} - -test_response_allowed { - body := main with input as testdata.example_pod_doesnt_have_node_selector - body.response.allowed == true -} - -test_isPod_true { - isPod with input as testdata.example_pod_has_node_selector -} \ No newline at end of file diff --git a/kafka_authorizer/src/test/resources/kafka_authz.rego b/kafka_authorizer/src/test/resources/kafka_authz.rego index 9b061d33..0269a15b 100644 --- a/kafka_authorizer/src/test/resources/kafka_authz.rego +++ b/kafka_authorizer/src/test/resources/kafka_authz.rego @@ -1,18 +1,20 @@ package kafka.authz -default allow = false +import rego.v1 -allow { +default allow := false + +allow if { not deny } -deny { +deny if { is_read_operation topic_contains_pii not consumer_is_whitelisted_for_pii } -deny { +deny if { is_write_operation topic_has_large_fanout not producer_is_whitelisted_for_large_fanout @@ -24,11 +26,11 @@ deny { # be loaded into OPA as raw JSON data. ############################################################################### -producer_whitelist = {"large-fanout": {"fanout_producer"}} +producer_whitelist := {"large-fanout": {"fanout_producer"}} -consumer_whitelist = {"pii": {"pii_consumer"}} +consumer_whitelist := {"pii": {"pii_consumer"}} -topic_metadata = { +topic_metadata := { "click-stream": {"tags": ["large-fanout"]}, "credit-scores": {"tags": ["pii"]}, } @@ -37,48 +39,48 @@ topic_metadata = { # Helper rules for checking whitelists. ############################################################################### -topic_contains_pii { - topic_metadata[topic_name].tags[_] == "pii" +topic_contains_pii if { + "pii" in topic_metadata[topic_name].tags } -topic_has_large_fanout { - topic_metadata[topic_name].tags[_] == "large-fanout" +topic_has_large_fanout if { + "large-fanout" in topic_metadata[topic_name].tags } -consumer_is_whitelisted_for_pii { - consumer_whitelist.pii[_] == principal.name +consumer_is_whitelisted_for_pii if { + principal.name in consumer_whitelist.pii } -producer_is_whitelisted_for_large_fanout { - producer_whitelist["large-fanout"][_] == principal.name +producer_is_whitelisted_for_large_fanout if { + principal.name in producer_whitelist["large-fanout"] } ############################################################################### # Helper rules for input processing. ############################################################################### -is_write_operation { +is_write_operation if { input.operation.name == "Write" } -is_read_operation { +is_read_operation if { input.operation.name == "Read" } -is_topic_resource { +is_topic_resource if { input.resource.resourceType.name == "Topic" } -topic_name = input.resource.name { +topic_name := input.resource.name if { is_topic_resource } -principal = {"fqn": parsed.CN, "name": cn_parts[0]} { +principal := {"fqn": parsed.CN, "name": cn_parts[0]} if { parsed := parse_user(urlquery.decode(input.session.sanitizedUser)) cn_parts := split(parsed.CN, ".") } -parse_user(user) = {key: value | +parse_user(user) := {key: value | parts := split(user, ",") [key, value] := split(parts[_], "=") } diff --git a/kong_api_authz/integration/testdata/opa/bundle/httpapi/authz/policy.rego b/kong_api_authz/integration/testdata/opa/bundle/httpapi/authz/policy.rego index 8d3a0989..14d55840 100644 --- a/kong_api_authz/integration/testdata/opa/bundle/httpapi/authz/policy.rego +++ b/kong_api_authz/integration/testdata/opa/bundle/httpapi/authz/policy.rego @@ -1,11 +1,13 @@ package httpapi.authz +import rego.v1 + # Deny access by default -default allow = false +default allow := false # Allows admin to access '/status' endpoints -allow { - input.method == "GET" - glob.match("/status**", ["/"], input.path) - input.token.payload.role == "admin" -} \ No newline at end of file +allow if { + input.method == "GET" + glob.match("/status**", ["/"], input.path) + input.token.payload.role == "admin" +} diff --git a/pam_opa/docker/policy/display.rego b/pam_opa/docker/policy/display.rego index 79863101..a8eaa983 100644 --- a/pam_opa/docker/policy/display.rego +++ b/pam_opa/docker/policy/display.rego @@ -2,7 +2,10 @@ # in the PAM configuration file. package display -display_spec = [ +import rego.v1 + +# regal ignore:rule-name-repeats-package +display_spec := [ { "message": "Welcome to the OPA-PAM demonstration.", "style": "info", @@ -17,4 +20,4 @@ display_spec = [ "style": "prompt_echo_off", "key": "secret", }, -] \ No newline at end of file +] diff --git a/pam_opa/docker/policy/pull.rego b/pam_opa/docker/policy/pull.rego index ea79505b..ce9d1127 100644 --- a/pam_opa/docker/policy/pull.rego +++ b/pam_opa/docker/policy/pull.rego @@ -2,8 +2,10 @@ # in the PAM configuration file. package pull +import rego.v1 + # JSON files to pull. -files = ["/etc/host_identity.json"] +files := ["/etc/host_identity.json"] # env_vars to pull. -env_vars = [] \ No newline at end of file +env_vars := [] diff --git a/pam_opa/docker/policy/sshd_authz.rego b/pam_opa/docker/policy/sshd_authz.rego index e9831ece..35feb43b 100644 --- a/pam_opa/docker/policy/sshd_authz.rego +++ b/pam_opa/docker/policy/sshd_authz.rego @@ -2,24 +2,22 @@ # in the sshd PAM configuration file. package sshd.authz -import input.display_responses -import input.pull_responses -import input.sysinfo +import rego.v1 -default allow = false +default allow := false -allow { +allow if { # Verify user input. - display_responses.last_name = "ramesh" - display_responses.secret = "suresh" + input.display_responses.last_name == "ramesh" + input.display_responses.secret == "suresh" # Only allow running on host_id "frontend" - pull_responses.files["/etc/host_identity.json"].host_id = "frontend" + input.pull_responses.files["/etc/host_identity.json"].host_id == "frontend" # Only authorize user "ops" - sysinfo.pam_username = "ops" + input.sysinfo.pam_username = "ops" } -errors["You cannot pass!"] { +errors contains "You cannot pass!" if { not allow -} \ No newline at end of file +} diff --git a/pam_opa/docker/policy/sudo_authz.rego b/pam_opa/docker/policy/sudo_authz.rego index f72fabda..a001f94f 100644 --- a/pam_opa/docker/policy/sudo_authz.rego +++ b/pam_opa/docker/policy/sudo_authz.rego @@ -2,24 +2,22 @@ # in the sudo PAM configuration file. package sudo.authz -import input.display_responses -import input.pull_responses -import input.sysinfo +import rego.v1 -default allow = false +default allow := false -allow { +allow if { # Verify user input. - display_responses.last_name = "ramesh" - display_responses.secret = "suresh" + input.display_responses.last_name == "ramesh" + input.display_responses.secret == "suresh" # Only allow running on host_id "frontend" - pull_responses.files["/etc/host_identity.json"].host_id = "frontend" + input.pull_responses.files["/etc/host_identity.json"].host_id == "frontend" # Only authorize user "ops" - sysinfo.pam_username = "ops" + input.sysinfo.pam_username == "ops" } -errors["You cannot pass!"] { +errors contains "You cannot pass!" if { not allow -} \ No newline at end of file +} diff --git a/puppet_example/puppet_authz.rego b/puppet_example/puppet_authz.rego index 8a4bda83..d7166f59 100644 --- a/puppet_example/puppet_authz.rego +++ b/puppet_example/puppet_authz.rego @@ -1,51 +1,52 @@ package puppet.authz +import rego.v1 + +# regal ignore:unresolved-import import data.git -import input.puppet.catalog -default allow = false +default allow := false -allow { not deny } +allow if not deny -deny { - resource = catalog.resources[resource_index] - resource.type = "File" - startswith(resource.title, "/etc/app") - resource_author[resource_index] = email - not app_team[email] +deny if { + some resource_index, resource in input.puppet.catalog.resources + resource.type == "File" + startswith(resource.title, "/etc/app") + email := resource_author[resource_index] + not email in app_team } -deny { - resource = catalog.resources[resource_index] - resource.type = "File" - startswith(resource.title, "/etc/infra") - resource_author[resource_index] = email - not infra_team[email] +deny if { + some resource_index, resource in input.puppet.catalog.resources + resource.type == "File" + startswith(resource.title, "/etc/infra") + email := resource_author[resource_index] + not email in infra_team } -resource_author[resource_index] = email { - - # For each "File" resource... - resource = catalog.resources[resource_index] - resource.type = "File" +resource_author[resource_index] := email if { + # For each "File" resource... + some resource_index, resource in input.puppet.catalog.resources + resource.type == "File" - # Compute the Puppet manifest filename relative to Git repository root... - count(source_root_dir, prefix_length) - substring(resource.file, prefix_length, -1, local_file) + # Compute the Puppet manifest filename relative to Git repository root... + prefix_length := count(source_root_dir) + local_file := substring(resource.file, prefix_length, -1) - # Lookup author for resource using the line number and Git blame data. - blame_entry = git[local_file] - email = blame_entry[resource.line]["Author"] + # Lookup author for resource using the line number and Git blame data. + blame_entry := git[local_file] + email := blame_entry[resource.line].Author } -app_team = { - "alice@acmecorp.com", - "bob@acmecorp.com", +app_team := { + "alice@acmecorp.com", + "bob@acmecorp.com", } -infra_team = { - "betty@acmecorp.com", - "chris@acmecorp.com", +infra_team := { + "betty@acmecorp.com", + "chris@acmecorp.com", } -source_root_dir = "/code/" +source_root_dir := "/code/" diff --git a/simplecov/example/policy.rego b/simplecov/example/policy.rego index 24732cd0..a995b393 100644 --- a/simplecov/example/policy.rego +++ b/simplecov/example/policy.rego @@ -1,9 +1,11 @@ package policy -deny["foo"] { - input.foo == "bar" +import rego.v1 + +deny contains "foo" if { + input.foo == "bar" } -deny["bar"] { - input.bar == "foo" +deny contains "bar" if { + input.bar == "foo" } diff --git a/simplecov/example/policy_test.rego b/simplecov/example/policy_test.rego index 83f63d7a..f752c25e 100644 --- a/simplecov/example/policy_test.rego +++ b/simplecov/example/policy_test.rego @@ -1,5 +1,9 @@ -package policy +package policy_test -test_deny { - deny with input as {"foo": "bar"} +import rego.v1 + +import data.policy + +test_deny if { + policy.deny with input as {"foo": "bar"} } diff --git a/simplecov/simplecov.rego b/simplecov/simplecov.rego index df5636f3..aa4b994f 100644 --- a/simplecov/simplecov.rego +++ b/simplecov/simplecov.rego @@ -1,49 +1,51 @@ package simplecov -import future.keywords +import rego.v1 -from_opa := { - "coverage": coverage -} +from_opa := {"coverage": coverage} -coverage[file] = obj { - some file, report in input.files - obj := { - "lines": to_lines(report) - } +coverage[file] := obj if { + some file, report in input.files + obj := {"lines": to_lines(report)} } -covered_map(report) = cm { - covered := object.get(report, "covered", []) - cm := {line: 1 | some item in covered - some line in numbers.range(item.start.row, item.end.row)} +covered_map(report) := cm if { + covered := object.get(report, "covered", []) + cm := {line: 1 | + some item in covered + some line in numbers.range(item.start.row, item.end.row) + } } -not_covered_map(report) = ncm { - not_covered := object.get(report, "not_covered", []) - ncm := {line: 0 | some item in not_covered - some line in numbers.range(item.start.row, item.end.row)} +not_covered_map(report) := ncm if { + not_covered := object.get(report, "not_covered", []) + ncm := {line: 0 | + some item in not_covered + some line in numbers.range(item.start.row, item.end.row) + } } -to_lines(report) = lines { - cm := covered_map(report) - ncm := not_covered_map(report) - keys := sort([line | some line, _ in object.union(cm, ncm)]) - last := keys[count(keys) - 1] +to_lines(report) := lines if { + cm := covered_map(report) + ncm := not_covered_map(report) + keys := sort([line | some line, _ in object.union(cm, ncm)]) + last := keys[count(keys) - 1] - lines := [value | some i in numbers.range(1, last) - value := to_value(cm, ncm, i)] + lines := [value | + some i in numbers.range(1, last) + value := to_value(cm, ncm, i) + ] } -to_value(cm, _, line) = 1 { - cm[line] +to_value(cm, _, line) := 1 if { + cm[line] } -to_value(_, ncm, line) = 0 { - ncm[line] +to_value(_, ncm, line) := 0 if { + ncm[line] } -to_value(cm, ncm, line) = null { - not cm[line] - not ncm[line] +to_value(cm, ncm, line) := null if { + not cm[line] + not ncm[line] } diff --git a/sonarcloud/example/policy.rego b/sonarcloud/example/policy.rego index 24732cd0..a995b393 100644 --- a/sonarcloud/example/policy.rego +++ b/sonarcloud/example/policy.rego @@ -1,9 +1,11 @@ package policy -deny["foo"] { - input.foo == "bar" +import rego.v1 + +deny contains "foo" if { + input.foo == "bar" } -deny["bar"] { - input.bar == "foo" +deny contains "bar" if { + input.bar == "foo" } diff --git a/sonarcloud/example/policy_test.rego b/sonarcloud/example/policy_test.rego index 83f63d7a..f124d201 100644 --- a/sonarcloud/example/policy_test.rego +++ b/sonarcloud/example/policy_test.rego @@ -1,5 +1,9 @@ -package policy +package policy_test -test_deny { - deny with input as {"foo": "bar"} +import rego.v1 + +import data.policy + +test_deny if { + count(policy.deny) == 1 with input as {"foo": "bar"} } diff --git a/wasm/cloudflare-worker/example.rego b/wasm/cloudflare-worker/example.rego index 879b4766..d58d7ad1 100644 --- a/wasm/cloudflare-worker/example.rego +++ b/wasm/cloudflare-worker/example.rego @@ -1,10 +1,12 @@ package example -allow { - input.method = "GET" +import rego.v1 + +allow if { + input.method == "GET" } -allow { - input.method = "POST" - input.path = "/api" +allow if { + input.method == "POST" + input.path == "/api" }