Skip to content

Commit

Permalink
Merge pull request #760 from jhrozek/artifacts_rule_eval
Browse files Browse the repository at this point in the history
Improve artifact support by storing artifact_id in the rule evaluation table and store artifact information during webhook processing
  • Loading branch information
jhrozek authored Aug 30, 2023
2 parents 4400115 + 2217c4f commit c8c4e92
Show file tree
Hide file tree
Showing 23 changed files with 3,018 additions and 2,432 deletions.
2 changes: 2 additions & 0 deletions cmd/cli/app/rule_type/rtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ func readEntityFromFile(fpath string, entType pb.Entity) (protoreflect.ProtoMess
switch entType {
case pb.Entity_ENTITY_REPOSITORIES:
out = &pb.RepositoryResult{}
case pb.Entity_ENTITY_ARTIFACTS:
out = &pb.VersionedArtifact{}
default:
return nil, fmt.Errorf("unknown entity type: %s", entType)
}
Expand Down
4 changes: 2 additions & 2 deletions database/migrations/000001_init.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ CREATE TABLE rule_evaluation_status (
eval_status eval_status_types NOT NULL,
-- polimorphic references. A status may be associated with a repository, build environment or artifact
repository_id INTEGER REFERENCES repositories(id) ON DELETE CASCADE,
artifact_id INTEGER REFERENCES artifacts(id) ON DELETE CASCADE,
-- These will be added later
-- artifact_id INTEGER REFERENCES artifacts(id) ON DELETE CASCADE,
-- build_environment_id INTEGER REFERENCES build_environments(id) ON DELETE CASCADE,
details TEXT NOT NULL,
last_updated TIMESTAMP NOT NULL DEFAULT NOW()
Expand All @@ -240,7 +240,7 @@ CREATE UNIQUE INDEX users_organization_id_username_lower_idx ON users (organizat
CREATE UNIQUE INDEX repositories_repo_id_idx ON repositories(repo_id);
CREATE UNIQUE INDEX policies_group_id_policy_name_idx ON policies(provider, group_id, name);
CREATE UNIQUE INDEX rule_type_idx ON rule_type(provider, group_id, name);
CREATE UNIQUE INDEX rule_evaluation_status_results_idx ON rule_evaluation_status(policy_id, repository_id, entity, rule_type_id);
CREATE UNIQUE INDEX rule_evaluation_status_results_idx ON rule_evaluation_status(policy_id, repository_id, COALESCE(artifact_id, 0), entity, rule_type_id);
CREATE UNIQUE INDEX artifact_name_lower_idx ON artifacts (repository_id, LOWER(artifact_name));
CREATE UNIQUE INDEX artifact_versions_idx ON artifact_versions (artifact_id, sha);

Expand Down
24 changes: 17 additions & 7 deletions database/query/policy_status.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ INSERT INTO rule_evaluation_status (
INSERT INTO rule_evaluation_status (
policy_id,
repository_id,
artifact_id,
rule_type_id,
entity,
eval_status,
details,
last_updated
) VALUES ($1, $2, $3, $4, $5, $6, NOW())
ON CONFLICT(policy_id, repository_id, entity, rule_type_id) DO UPDATE SET
eval_status = $5,
details = $6,
) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
ON CONFLICT(policy_id, repository_id, COALESCE(artifact_id, 0), entity, rule_type_id) DO UPDATE SET
eval_status = $6,
details = $7,
last_updated = NOW()
WHERE rule_evaluation_status.policy_id = $1
AND rule_evaluation_status.repository_id = $2
AND rule_evaluation_status.rule_type_id = $3
AND rule_evaluation_status.entity = $4;
AND rule_evaluation_status.artifact_id = $3
AND rule_evaluation_status.rule_type_id = $4
AND rule_evaluation_status.entity = $5;

-- name: GetPolicyStatusByIdAndGroup :one
SELECT p.id, p.name, ps.policy_status, ps.last_updated FROM policy_status ps
Expand All @@ -48,4 +50,12 @@ SELECT res.eval_status as eval_status, res.last_updated as last_updated, res.det
FROM rule_evaluation_status res
INNER JOIN repositories repo ON repo.id = res.repository_id
INNER JOIN rule_type rt ON rt.id = res.rule_type_id
WHERE res.policy_id = $1 AND (res.repository_id = $2 OR $2 IS NULL);
WHERE res.policy_id = $1 AND
(
CASE
WHEN sqlc.narg(entity_type)::entities = 'repository' AND res.repository_id = sqlc.narg(entity_id)::integer THEN true
WHEN sqlc.narg(entity_type)::entities = 'artifact' AND res.artifact_id = sqlc.narg(entity_id)::integer THEN true
WHEN sqlc.narg(entity_id)::integer IS NULL THEN true
ELSE false
END
);
39 changes: 25 additions & 14 deletions docs/docs/protodocs/proto.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions examples/github/policies/policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ artifact:
rules:
- type: artifact_signature
params:
tag: main
artifactName: test
tags: [main]
name: test
def:
is_signed: true
is_verified: true
Expand Down
4 changes: 2 additions & 2 deletions examples/github/policies/policy_artifact.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ artifact:
rules:
- type: artifact_signature
params:
tag: main
artifactName: test
tags: [main]
name: test
def:
is_signed: true
is_verified: true
Expand Down
28 changes: 17 additions & 11 deletions examples/github/rule-types/artifact_signature.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,23 @@ def:
# Defines the schema for parameters that will be passed to the rule
param_schema:
properties:
artifactName:
name:
type: string
description: "The name of the artifact to check."
tag:
type: string
description: "The tag of the artifact to check."
tags:
"type": array
"items": {
"type": "string"
}
description: "The tags of the artifact to check. Must be a subset of the tags the artifact has"
type:
"type": string
"default": "container"
"enum": ["container"]
description: "The type of artifact to check. Currently only container is supported."
required:
- artifactName
- tag
- name
- tags
# Defines the schema for writing a rule with this rule being checked
rule_schema:
properties:
Expand All @@ -37,11 +45,9 @@ def:
description: "Set to true to enforce artifact signature being verified."
# Defines the configuration for ingesting data relevant for the rule
ingest:
type: builtin
builtin:
# method will be called using reflection, and will accept a generic json payload
# it will also return a generic json payload
method: ValidateSignature
type: artifact
# Currently no configuration
artifact: {}
# Defines the configuration for evaluating data ingested against the given policy
eval:
type: jq
Expand Down
28 changes: 28 additions & 0 deletions examples/github/versioned_artifact.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
artifact:
artifactId: 5482209
name: test
owner: jakubtestorg
packageUrl: ghcr.io/jakubtestorg/testrepo:main
repository: jakubtestorg/testrepo
type: CONTAINER
visibility: public
version:
createdAt: '2023-08-28T14:02:18Z'
github_workflow:
commit_sha: 542ff1ded187631de1077ef42c07a7b723ff0963
name: Docker
repository: jakubtestorg/testrepo
trigger: workflow_dispatch
sha: sha256:059105cbc9331f6cef5aeb4bff1c0c7be0126d3e5eee0fdfbd45718a6cdd9ea3
signature_verification:
cert_identity: >-
https://github.com/jakubtestorg/testrepo/.github/workflows/docker-image.yml@refs/heads/main
cert_issuer: https://token.actions.githubusercontent.com
is_bundle_verified: true
is_signed: true
is_verified: true
rekor_log_id: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
rekor_log_index: 33115087
tags:
- main
versionId: 122634734
Loading

0 comments on commit c8c4e92

Please sign in to comment.