Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add runtime trace predicate type #111

Merged
merged 1 commit into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions spec/predicates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ our [vetting process], and may be of general interest:
- [Link]: For migration from [in-toto 0.9].
- [SCAI Report]: Evidence-based assertions about software artifact and
supply chain attributes or behavior.
- [Runtime Traces]: To capture runtime traces of software supply chain
operations.

[Link]: link.md
[New Predicate Guidelines]: ../../docs/new_predicate_guidelines.md
[SCAI Report]: scai.md
[SLSA Provenance]: https://slsa.dev/provenance
[in-toto 0.9]: https://github.com/in-toto/docs/blob/master/in-toto-spec.md#44-file-formats-namekeyid-prefixlink
[vetting process]: ../../docs/new_predicate_guidelines.md#vetting-process
[Runtime Traces]: runtime-trace.md
273 changes: 273 additions & 0 deletions spec/predicates/runtime-trace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
# Predicate type: Runtime Trace

Type URI: https://in-toto.io/attestation/runtime-trace/v0.1

Version: 0.1.0
adityasaky marked this conversation as resolved.
Show resolved Hide resolved

Authors: Parth Patel (@pxp928), Shripad Nadgowda (@nadgowdas),
Aditya Sirish A Yelgundhalli (@adityasaky)

## Purpose

This predicate is used to describe system events that were part of some software
supply chain step, for example, the build process of an artifact. Supply chain
operations today are complex and opaque with little to no insights into
underlying system operations. However, there are emerging introspection
techniques that now allow us to monitor and capture system event logs during the
monitored operation.

## Use Cases

Generally, this predicate can be used to express a runtime trace of any
operation. The predicate specification does not mandate any specific monitoring
tool or technology. The schema can be used to express runtime traces of anything
that can be traced or monitored, from an operation spawned by a user using a CLI
command to tasks performed in CI systems. The primary use case driving the
development of this predicate is its applicability to runtime traces of build
processes.

This attestation can be used in conjunction with provenance attestations to
leverage observability to attest to various SLSA requirements. The runtime trace
can prove the build was invoked via a script, that the build was executed in a
hermetic environment with no network access, and so on.

## Prerequisites
adityasaky marked this conversation as resolved.
Show resolved Hide resolved

Understanding of monitoring tools and the larger in-toto attestation framework.

## Model

`monitor` identifies the specific instance of a tool that’s observing the target
process and details the configurations of the monitor, while `monitoredProcess`
contains information that when put together uniquely identifies the exact
instance of the job being observed. The `monitorLog` field contains the actual
runtime trace information.

## Schema

```json
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [{ ... }],
"predicateType": "https://in-toto.io/attestation/runtime-trace/v0.1",
"predicate": {
"monitor": {
"type": "<TypeURI>",
"configSource": "<ResourceDescriptor>",
"tracePolicy": { /* object */ }
},
"monitoredProcess": {
"hostID": "<URI>",
"type": "<URI>",
"event": "<STRING>"
},
"monitorLog": {
"process": [
{ /* object */ }
],
"network": [
{ /* object */ }
],
"fileAccess": ["<ResourceDescriptor>", ...]
},
"metadata": {
"buildStartedOn": "<TIMESTAMP>",
"buildFinishedOn": "<TIMESTAMP>"
}
}
}
adityasaky marked this conversation as resolved.
Show resolved Hide resolved
```

### Parsing Rules

This predicate follows the in-toto attestation parsing rules. Summary:

- Consumers MUST ignore unrecognized fields.
- The `predicateType` URI includes the major version number and will always
change whenever there is a backwards incompatible change.
- Minor version changes are always backwards compatible and “monotonic.” Such
changes do not update the `predicateType`.
- Producers MAY add extension fields using field names that are unlikely to
collide with names used by other producers. Field names SHOULD avoid using
characters like `.` and `$`.
- Fields marked _optional_ MAY be unset or null, and should be treated
equivalently. Both are equivalent to empty for object or array values.

### Fields

`monitor` _object_, _required_

Identifies the specific monitor instance used to trace the runtime.

`monitor.type` _TypeURI_, _required_

URI indicating the monitor’s type.

`monitor.configSource` ResourceDescriptor, _optional_

Effectively a pointer to the monitor's configuration.
adityasaky marked this conversation as resolved.
Show resolved Hide resolved

`monitor.tracePolicy` _object_, _optional_

Indicates the trace policy used for the monitoring event that generated the
runtime trace. The trace policy's format is dependent on the monitor used, and
so it must be parsed after identifying the monitor using `monitor.type`.

FIXME: should this be optional?
adityasaky marked this conversation as resolved.
Show resolved Hide resolved

`monitoredProcess` _object_, _required_

Identifies the process being monitored.

`monitoredProcess.hostID` _string (URI)_, _required_

URI indicating the process host’s identity.

`monitoredProcess.type` _string (TypeURI)_, _required_

URI indicating the type of process performed. Ex: when monitoring a build, this
field records the build type.

`monitoredProcess.event` _string_, _required_

String identifying the specific job or task associated with the attestation.

`monitorLog` _object_, _required_
Copy link

@itaysk itaysk Feb 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably very subjective but trace might be more descriptive in this case than monitor. the attestation is also called runtime trace. and it's definition is a trace policy. so calling this monitor here is standing out for me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair! I think we've got a couple of different field rename suggestions to consider and implement here.


Record of events that were traced by the monitor. At least one of `process`,
`network`, and `fileAccess` must be present.

`monitorLog.process` _list of objects_, _optional_

Record of processes observed by monitor. The exact format of this field is
currently dependent on the monitor, and can be determined using `monitor.type`.
In future, after consulting different monitors, this field may have a consistent
schema.

`monitorLog.network` _list of objects_, _optional_

Record of network activity observed by monitor. The exact format of this field
is currently dependent on the monitor, and can be determined using
`monitor.type`. In future, after consulting different monitors, this field may
have a consistent schema.

`monitorLog.fileAccess` _list of ResourceDescriptor objects_, _optional_

Record of files accessed during the monitored process. A complete list of
adityasaky marked this conversation as resolved.
Show resolved Hide resolved
_materials_ can be derived from this information. Each entry in this list is
adityasaky marked this conversation as resolved.
Show resolved Hide resolved
expected to record the path of the file and one or more digests of the file, but
as each entry is an instance of _ResourceDescriptor_, other supported
information can also be captured. This field is a list rather than a key-value
map because a single file may be used multiple times during the build process.
Further, some files that are accessed may _change_ during the build process, and
so, different entries for the same file may have different digests.

Note: While this predicate can be used to log file accesses, the actual
technique used to capture the file access event has some implications. If a
synchronous monitor, for example one that uses `ptrace` to trace the file access
system calls, is used, then the build process can be paused while the file's
digest is calculated and stored. However, asynchronous monitors such as those
using eBPF cannot pause the build process before the file is actually used.
Therefore, they cannot make as strong guarantees about the digests of the files
accessed. Verifiers using runtime trace attestations for file accesses must be
careful about what guarantees they are actually getting based on how the build
process was monitored.

`metadata` _object_, _optional_

Other properties of the monitoring event.

`metadata.buildStartedOn` _Timestamp_, _optional_

`metadata.buildFinishedOn` _Timestamp_, _optional_

## Example

```json
{
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://in-toto.io/attestation/runtime-trace/v0.1",
"subject": [
{
"name": "ttl.sh/testin123",
"digest": {
"sha256": "def2bdf8cee687d5889d51923d7907c441f1a61958f1e5dfb07f53041c83745f"
}
}
],
"predicate": {
"monitor": {
"type": "https://github.com/cilium/tetragon/v0.8.4",
"configSource": {},
"tracePolicy": {
"policies": [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trace policies would also need to define how they are configured. Below is a snippet from an output from tetragon. This still needs to be re-worked and formatted to be much more generalized. Not a representation of the final format, but wanted to put an example here for discussion.

"policies": [
          {
            "Name": "connect",
            "Config": "Name: /var/lib/tetragon/bpf_generic_kprobe_v53.o, Attach: tcp_connect, Label: kprobe/generic_kprobe, PinPath: gkp-sensor-1-gkp-0-tcp_connect_prog, RetProbe: false, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:0};Name: /var/lib/tetragon/bpf_generic_kprobe_v53.o, Attach: tcp_close, Label: kprobe/generic_kprobe, PinPath: gkp-sensor-1-gkp-1-tcp_close_prog, RetProbe: false, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:1};Name: /var/lib/tetragon/bpf_generic_kprobe_v53.o, Attach: tcp_sendmsg, Label: kprobe/generic_kprobe, PinPath: gkp-sensor-1-gkp-2-tcp_sendmsg_prog, RetProbe: false, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:2}"
          },
          {
            "Name": "sys-read-follow-prefix",
            "Config": "Name: /var/lib/tetragon/bpf_generic_kprobe_v53.o, Attach: fd_install, Label: kprobe/generic_kprobe, PinPath: gkp-sensor-4-gkp-3-fd_install_prog, RetProbe: false, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:3};Name: /var/lib/tetragon/bpf_generic_kprobe_v53.o, Attach: __x64_sys_close, Label: kprobe/generic_kprobe, PinPath: gkp-sensor-4-gkp-4-__x64_sys_close_prog, RetProbe: false, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:4};Name: /var/lib/tetragon/bpf_generic_kprobe_v53.o, Attach: __x64_sys_read, Label: kprobe/generic_kprobe, PinPath: gkp-sensor-4-gkp-5-__x64_sys_read_prog, RetProbe: false, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:5};Name: /var/lib/tetragon/bpf_generic_retkprobe_v53.o, Attach: __x64_sys_read, Label: kprobe/generic_retkprobe, PinPath: gkp-sensor-4-gkp-5-__x64_sys_read_ret_prog, RetProbe: true, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:5};Name: /var/lib/tetragon/bpf_generic_kprobe_v53.o, Attach: __x64_sys_write, Label: kprobe/generic_kprobe, PinPath: gkp-sensor-4-gkp-6-__x64_sys_write_prog, RetProbe: false, ErrorFatal: true, Override: false, Type: generic_kprobe, LoaderDate: {ID:6}"
          }
        ]
      }

{
"Name": "connect",
"Config": ""
},
{
"Name": "sys-read-follow-prefix",
"Config": ""
}
]
}
},
"monitoredProcess": {
"hostID": "https://tekton.dev/chains/v2",
"type": "https://tekton.dev/attestations/chains@v2",
"event": "run-image-pipelinerun-build-trusted"
},
"monitorLog": {
"process": [
adityasaky marked this conversation as resolved.
Show resolved Hide resolved
{
"eventType": "process",
"processBinary": "/ko-app/entrypoint",
"arguments": [
"init /ko-app/entrypoint /tekton/bin/entrypoint step-prepare step-create step-results"
],
"privileged": null
},
{
"eventType": "process",
"processBinary": "/bin/sh",
"arguments": [
"-c \"scriptfile=\"/tekton/scripts/script-0-vjklb\"\ntouch ${scriptfile} && chmod +x ${scriptfile}\ncat > ${s\" \"riptfile} << '_EOF_'\nIyEvdXNyL2Jpbi9lbnYgYmFzaApzZXQgLWUKCmlmIFtbICJ0cnVlIiA9PSAidHJ1ZSIgXV07IHRoZW\" KICBlY2hvICI+IFNldHRpbmcgcGVybWlzc2lvbnMgb24gJy93b3Jrc3BhY2UvY2FjaGUnLi4uIgogIGNob3duIC1SICIxMDAwOj wMDAiICIvd29ya3NwYWNlL2NhY2hlIgpmaQoKZm9yIHBhdGggaW4gIi90ZWt0b24vaG9tZSIgIi9sYXllcnMiICIvd29ya3NwYW lL3NvdXJjZSI7IGRvCiAgZWNobyAiPiBTZXR0aW5nIHBlcm1pc3Npb25zIG9uICckcGF0aCcuLi4iCiAgY2hvd24gLVIgIjEwMD 6MTAwMCIgIiRwYXRoIgoKICBpZiBbWyAiJHBhdGgiID09ICIvd29ya3NwYWNlL3NvdXJjZSIgXV07IHRoZW4KICAgICAgY2htb2 gNzc1ICIvd29ya3NwYWNlL3NvdXJjZSIKICBmaQpkb25lCgplY2hvICI+IFBhcnNpbmcgYWRkaXRpb25hbCBjb25maWd1cmF0aW uLi4uIgpwYXJzaW5nX2ZsYWc9IiIKZW52cz0oKQpmb3IgYXJnIGluICIkQCI7IGRvCiAgICBpZiBbWyAiJGFyZyIgPT0gIi0tZW 2LXZhcnMiIF1dOyB0aGVuCiAgICAgICAgZWNobyAiLT4gUGFyc2luZyBlbnYgdmFyaWFibGVzLi4uIgogICAgICAgIHBhcnNpbm fZmxhZz0iZW52LXZhcnMiCiAgICBlbGlmIFtbICIkcGFyc2luZ19mbGFnIiA9PSAiZW52LXZhcnMiIF1dOyB0aGVuCiAgICAgIC"
],
"privileged": null
},
{
"eventType": "process",
"processBinary": "/bin/touch",
"arguments": [
"/tekton/scripts/script-0-vjklb"
],
"privileged": null
},
...,
{
"eventType": "exit",
"processBinary": "/bin/sh",
"arguments": [
"",
"-c \"scriptfile=\"/tekton/scripts/script-0-vjklb\"\ntouch ${scriptfile} && chmod +x ${scriptfile}\ncat > ${s\" \"riptfile} << '_EOF_'\nIyEvdXNyL2Jpbi9lbnYgYmFzaApzZXQgLWUKCmlmIFtbICJ0cnVlIiA9PSAidHJ1ZSIgXV07IHRoZW\" KICBlY2hvICI+IFNldHRpbmcgcGVybWlzc2lvbnMgb24gJy93b3Jrc3BhY2UvY2FjaGUnLi4uIgogIGNob3duIC1SICIxMDAwOj wMDAiICIvd29ya3NwYWNlL2NhY2hlIgpmaQoKZm9yIHBhdGggaW4gIi90ZWt0b24vaG9tZSIgIi9sYXllcnMiICIvd29ya3NwYW lL3NvdXJjZSI7IGRvCiAgZWNobyAiPiBTZXR0aW5nIHBlcm1pc3Npb25zIG9uICckcGF0aCcuLi4iCiAgY2hvd24gLVIgIjEwMD 6MTAwMCIgIiRwYXRoIgoKICBpZiBbWyAiJHBhdGgiID09ICIvd29ya3NwYWNlL3NvdXJjZSIgXV07IHRoZW4KICAgICAgY2htb2 gNzc1ICIvd29ya3NwYWNlL3NvdXJjZSIKICBmaQpkb25lCgplY2hvICI+IFBhcnNpbmcgYWRkaXRpb25hbCBjb25maWd1cmF0aW uLi4uIgpwYXJzaW5nX2ZsYWc9IiIKZW52cz0oKQpmb3IgYXJnIGluICIkQCI7IGRvCiAgICBpZiBbWyAiJGFyZyIgPT0gIi0tZW 2LXZhcnMiIF1dOyB0aGVuCiAgICAgICAgZWNobyAiLT4gUGFyc2luZyBlbnYgdmFyaWFibGVzLi4uIgogICAgICAgIHBhcnNpbm fZmxhZz0iZW52LXZhcnMiCiAgICBlbGlmIFtbICIkcGFyc2luZ19mbGFnIiA9PSAiZW52LXZhcnMiIF1dOyB0aGVuCiAgICAgIC"
],
"privileged": null
},
{
"eventType": "exit",
"processBinary": "/tekton/bin/entrypoint",
"arguments": [
"",
"-wait_file /tekton/downward/ready -wait_file_content -post_file /tekton/run/0/out -termination_path /tekton/termination -step_metadata_dir /tekton/run/0/status -results APP_IMAGE_DIGEST,APP_IMAGE_URL -entrypoint /tekton/scripts/script-0-vjklb -- --env-vars"
],
"privileged": null
}
]
},
"metadata": {
"buildStartedOn": "2022-10-13T22:55:50Z",
"buildFinishedOn": "2022-10-13T22:56:17Z"
}
}
}
```