{"id":13645969,"url":"https://github.com/rode/rode-legacy","last_synced_at":"2025-04-21T17:31:43.676Z","repository":{"id":51539670,"uuid":"234662553","full_name":"rode/rode-legacy","owner":"rode","description":"cloud native software supply chain ☁️🔗","archived":true,"fork":false,"pushed_at":"2021-02-15T14:54:05.000Z","size":17524,"stargazers_count":63,"open_issues_count":2,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-20T17:04:58.960Z","etag":null,"topics":["cloud-native","kubernetes","security"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null}},"created_at":"2020-01-18T01:00:08.000Z","updated_at":"2025-02-10T20:44:02.000Z","dependencies_parsed_at":"2022-09-13T03:12:25.927Z","dependency_job_id":null,"html_url":"https://github.com/rode/rode-legacy","commit_stats":null,"previous_names":["liatrio/rode"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rode%2Frode-legacy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rode%2Frode-legacy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rode%2Frode-legacy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rode%2Frode-legacy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rode","download_url":"https://codeload.github.com/rode/rode-legacy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250100509,"owners_count":21374960,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloud-native","kubernetes","security"],"created_at":"2024-08-02T01:02:46.014Z","updated_at":"2025-04-21T17:31:42.545Z","avatar_url":"https://github.com/rode.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Warning: this project has been deprecated\nAs of 12/18/2020 the new home for all `rode` development will be located at [github.com/rode](https://github.com/rode) \n\n# ![](docs/logo.png) Rode \n![tag](https://github.com/liatrio/rode/workflows/tag/badge.svg)\n\u003e \\rōd\\ - a line (as of rope or chain) used to attach an anchor to a boat\n\nRode provides the collection, attestation and enforcement of policies in your software supply chain.  Watch the [demo](https://youtu.be/CyrbLQYUCbM?t=580) and [slides](https://www.slideshare.net/CaseyLee2/the-last-bottleneck-of-continuous-delivery/) from DeliveryConf for a quick introduction!\n\n![](docs/overview.png)\n\nThere are 3 primary components in rode: `collectors`, `attesters` and `enforcers`\n\n## Collectors\nCollectors are responsible for receiving events from external systems and converting them into [occurrences](https://github.com/grafeas/grafeas/blob/master/docs/grafeas_concepts.md#occurrences) in [Grafeas](https://github.com/grafeas/grafeas).\n\n![](docs/collectors.png)\n\nThe list of supported collectors is growing and currently includes:\n* **ECR Events** - image scan events are sent to an SQS queue via CloudWatch event rules.  A collector in rode processes the messages from the queue and converts them into [discovery](https://github.com/grafeas/grafeas/blob/master/docs/grafeas_concepts.md#kind-specific-schemas) and [vulnerability](https://github.com/grafeas/grafeas/blob/master/docs/grafeas_concepts.md#kind-specific-schemas) occurrences in Grafeas.\n* **Harbor Events** - image scan events are sent to a Rode endpoint.  A collector in rode processes the messages from the queue and converts them into [discovery](https://github.com/grafeas/grafeas/blob/master/docs/grafeas_concepts.md#kind-specific-schemas) and [vulnerability](https://github.com/grafeas/grafeas/blob/master/docs/grafeas_concepts.md#kind-specific-schemas) occurrences in Grafeas.\n\nCollectors are defined as `Collector` [custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/).  See below for an example:\n\n```yaml\napiVersion: rode.liatr.io/v1alpha1\nkind: Collector\nspec:\n  name: my_collector\n  type: ecr\n  queueName: my_ecr_event_queue\n```\n\n## Attesters\nAttesters monitor collectors for new `occurrences`.  Whenever a new occurrence is created on a [resource](https://github.com/grafeas/grafeas/blob/master/docs/grafeas_concepts.md#resource-urls), then all occurrences are loaded for that resource and passed in to [Open Policy Agent (OPA)](https://www.openpolicyagent.org/) to determine if all necessary occurrences exist for the resource.\n\nIf all occurrences exist and comply with the policy, then the attester will use its private PGP key to sign a new attestation for the resource and store the attestation in Grafeas.\n\n![](docs/attesters.png)\n\nAttesters are defined as `Attester` [custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/).  See below for an example:\n\n```yaml\napiVersion: rode.liatr.io/v1alpha1\nkind: Attester\nspec:\n  name: my_collector\n  pgp-secret: my_secret_name\n  policy: |\n    package my_collector\n\n    violation[{\"msg\":\"analysis failed\"}]{\n        input.occurrences[_].discovered.discovered.analysisStatus != \"FINISHED_SUCCESS\"\n    }\n    violation[{\"msg\":\"analysis not performed\"}]{\n        analysisStatus := [s | s := input.occurrences[_].discovered.discovered.analysisStatus]\n        count(analysisStatus) = 0\n    }\n    violation[{\"msg\":\"critical vulnerability found\"}]{\n        severityCount(\"CRITICAL\") \u003e 0\n    }\n    violation[{\"msg\":\"high vulnerability found\"}]{\n        severityCount(\"HIGH\") \u003e 10\n    }\n    severityCount(severity) = cnt {\n        cnt := count([v | v := input.occurrences[_].vulnerability.severity; v == severity])\n    }\n```\n\nThe PGP key is automatically generated and stored as a Kubernetes secret if it doesn't already exist.\n\n## Enforcers\nEnforcers are defined as [validating admission webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) that ensures the resource defined as an `image` in the `Pod` has been properly attested.\n\nEnforcers are configured to ensure the specified attester referenced in the namespace for the pod had successfully created an attestation. The namespace must include a label for enforcement to be activated:\n\n\n```yaml\n  \"rode.liatr.io/enforce\": true\n```\n\n![](docs/enforcers.png)\n\n# Installation\nThe easiest way to install rode is via the helm chart:\n\n```shell\nhelm repo add liatrio https://harbor.toolchain.lead.prod.liatr.io/chartrepo/public\nhelm upgrade -i rode liatrio/rode\n```\n\n## Elastic Container Registry\n\nSetup collectors, attesters and enforcers through a quickstart:\n\n```shell\nkubectl apply -f examples/aws-quickstart.yaml\n```\n\nThe ECR event collector requires the following IAM policy.  Either attach the policy to the EC2 instance or use IRSA and pass the role ARN to Helm:\n\n```shell\nhelm upgrade -i rode liatrio/rode --set rbac.serviceAccountAnnotations.\"eks\\.amazonaws\\.com/role-arn\"=arn:aws:iam::1234567890:role/RodeServiceAccount\n```\n\n```json\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"sqs:CreateQueue\"\n                \"sqs:SetQueueAttributes\",\n                \"sqs:GetQueueUrl\",\n                \"sqs:GetQueueAttributes\",\n                \"sqs:ReceiveMessage\",\n                \"sqs:DeleteMessage\",\n            ],\n            \"Resource\": \"*\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"events:PutTargets\",\n                \"events:PutRule\"\n            ],\n            \"Resource\": \"*\"\n        }\n    ]\n}\n```\n\n## Harbor\n\nIf Harbor is being utilized as a container registry, you can specify `harbor` as the collector type.\n\n```yaml\napiVersion: rode.liatr.io/v1alpha1\nkind: Collector\nspec:\n  name: my_collector\n  type: ecr\n  queueName: my_ecr_event_queue\n---\napiVersion: rode.liatr.io/v1alpha1\nkind: Collector\nmetadata: \n  name: harborCollector\n  finalizers:\n  - collectors.finalizers.rode.liatr.io\nspec:\n  harbor:\n    harborUrl: \"https://example.com\"\n    project: \"example-project\"\n    secret: \"default/harbor-harbor-core\"\n  type: harbor\n\n```\n\n# Development\nTo run locally you need to have Docker for Desktop running and your k8s context set to `docker-desktop`. Skaffold will automatically use the `local` profile which installs [LocalStack](https://github.com/localstack/localstack) to test the AWS ECR collector by mocking the SQS service.\n\nTo run controllers:\n\n```shell\nskaffold dev --port-forward\n```\n\nSetup collectors, attesters and enforcers:\n\n```shell\nkubectl apply -f examples/aws-quickstart.yaml\n```\n\nTo create an occurrence, use the aws cli to send a test message to LocalStack:\n\n```shell\naws sqs send-message \\\n    --endpoint-url http://localhost:30576 \\\n    --queue-url http://localhost:30576/queue/rode-ecr-event-collector  \\\n    --message-body file://test/sample_scan_event.json \n``` \n\n## Testing\n\nTo run unit tests \n\n```shell\ngo test -cover -tags unit ./...\n```\n\nTo run unit and integration tests Rode and LocalStack must be running. Follow the local development instructions above.\n```shell\ngo test ./...\n```\n\n## Testing Multi-Cluster Communication\n\nYou can test separating the policy and enforcement features of Rode by running both locally. This will deploy different instances of Rode into two different namespaces (`rode-policy` and `rode-enforcement`) so you can test the communication between the two instances.\n\n**Deploy the policy Rode instance**\n\n```shell\nskaffold run -p local,policy\n```\n\nThis will deploy Rode with Collector and Attester controllers and deploy the messaging service [Jetstream](https://github.com/nats-io/jetstream)\n\n**Deploy the enforcement Rode instance**\n\n```shell\nskaffold run -p local,enforcement\n```\n\nThis will deploy Rode with Enforcer and Cluster Enforcer controllers and the enforcer validating webhook. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frode%2Frode-legacy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frode%2Frode-legacy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frode%2Frode-legacy/lists"}