Skip to content

Commit

Permalink
ArtC: Add data.fileInformation.integrityProtection (#320)
Browse files Browse the repository at this point in the history
This new member allows publishers to include the checksum of the
artifact's file(s) when the artifact is announced, allowing consumers
to verify that the file they eventually download is the original file.
  • Loading branch information
magnusbaeck committed Oct 27, 2022
1 parent 55163e5 commit aafb9ec
Show file tree
Hide file tree
Showing 5 changed files with 576 additions and 3 deletions.
248 changes: 248 additions & 0 deletions definitions/EiffelArtifactCreatedEvent/3.3.0.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# Copyright 2017-2022 Ericsson AB and others.
# For a full list of individual contributors, please see the commit history.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
$schema: http://json-schema.org/draft-04/schema#
_abbrev: ArtC
_description: The EiffelArtifactCreatedEvent declares that a software
artifact has been created, what its coordinates are, what it contains
and how it was created.
type: object
properties:
meta:
$ref: ../EiffelMetaProperty/3.1.0.yml
data:
type: object
properties:
identity:
_description: The identity of the created artifact, in [purl
format](https://github.com/package-url/purl-spec).
_format: '[purl specification](https://github.com/package-url/purl-spec)'
type: string
pattern: '^pkg:'
fileInformation:
_description: A list of the artifact file contents. This information
is optional and, when included, MAY include a complete or
incomplete list of contents. In other words, it may be used
to highlight only particular files of interest, such as launcher
binaries or other entry-points.
type: array
items:
type: object
properties:
name:
_description: The name (including relative path from
the root of the artifact) on syntax appropriate for
the artifact packaging type.
type: string
tags:
_description: Any tags associated with the file, to support
navigation and identification of items of interest.
type: array
items:
type: string
integrityProtection:
_description: An optional object containing a digest of
the file's contents, i.e. a checksum, computed using
the specified algorithm.
type: object
properties:
alg:
_description: The cryptographic algorithm used to compute
the digest of the file's contents.
_format: One of the hash algorithms listed in section 1 of
[NIST FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf),
excluding "SHA-1".
type: string
enum:
- SHA-224
- SHA-256
- SHA-384
- SHA-512
- SHA-512/224
- SHA-512/256
digest:
_description: The digest of the file contents.
_format: A lowercase string of hexadecimal digits.
type: string
pattern: ^[0-9a-f]+$
required:
- alg
- digest
additionalProperties: false
required:
- name
additionalProperties: false
buildCommand:
_description: The command used to build the artifact within
the identified environment. Used for reproducability purposes.
type: string
requiresImplementation:
_description: |-
Defines whether this artifact requires an implementing artifact. This is typically used for interfaces requiring some backend implementation, although the interface does not presume to define _which_ implementation. Implicitly interpreted as "ANY" if undefined.
NONE signifies that there SHALL no implementations of this artifact. In other words, a composition containing another artifact identifying it in __data.implements__ would be illegal.
ANY signifies that there may or may not be implementations of this artifact.
EXACTLY_ONE signifies that a legal composition must contain one and only one implementation of this artifact.
AT_LEAST_ONE signifies that a legal composition must contain one or more implementations of this artifact.
type: string
enum:
- NONE
- ANY
- EXACTLY_ONE
- AT_LEAST_ONE
dependsOn:
_description: An array of [purl identified](https://github.com/package-url/purl-spec)
entities this artifact depends on. While not included in
the purl specification itself, the Eiffel protocol allows
version range notation according to [Maven syntax](https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN402)
to be used for the version component of the package identity.
Note that the purl specification always requires the version
component to be percent-encoded.
_format: '[purl specification](https://github.com/package-url/purl-spec)'
type: array
items:
type: string
pattern: '^pkg:'
implements:
_description: An array of [purl identified](https://github.com/package-url/purl-spec)
entities this artifact implements. The typical use case of
this is to identify interfaces implemented by this artifact.
While not included in the purl specification itself, the
Eiffel protocol allows version range notation according to
[Maven syntax](https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN402)
to be used for the version component of the package identity.
Note that the purl specification always requires the version
component to be percent-encoded.
_format: '[purl specification](https://github.com/package-url/purl-spec)'
type: array
items:
type: string
pattern: '^pkg:'
name:
_description: Any (colloquial) name of the artifact. Unlike
__data.identity__, this is not intended as an unambiguous
identifier of the artifact, but as a descriptive and human
readable name.
type: string
customData:
type: array
items:
$ref: ../EiffelCustomDataProperty/1.0.0.yml
required:
- identity
additionalProperties: false
links:
type: array
items:
$ref: ../EiffelEventLink/1.1.1.yml
required:
- meta
- data
- links
additionalProperties: false
_links:
CAUSE:
description: 'Identifies a cause of the event occurring. SHOULD
not be used in conjunction with __CONTEXT__: individual events
providing __CAUSE__ within a larger context gives rise to ambiguity.
It is instead recommended to let the root event of the context
declare __CAUSE__.'
required: false
multiple: true
targets:
any_type: true
types: []
COMPOSITION:
description: Identifies the composition from which this artifact
was built.
required: false
multiple: false
targets:
any_type: false
types:
- EiffelCompositionDefinedEvent
CONTEXT:
description: Identifies the activity or test suite of which this
event constitutes a part.
required: false
multiple: false
targets:
any_type: false
types:
- EiffelActivityTriggeredEvent
- EiffelTestSuiteStartedEvent
ENVIRONMENT:
description: Identifies the environment in which this artifact
was built.
required: false
multiple: false
targets:
any_type: false
types:
- EiffelEnvironmentDefinedEvent
FLOW_CONTEXT:
description: 'Identifies the flow context of the event: which is
the continuous integration and delivery flow in which this occurred
– e.g. which product, project, track or version this is applicable
to.'
required: false
multiple: true
targets:
any_type: false
types:
- EiffelFlowContextDefinedEvent
PREVIOUS_VERSION:
description: Identifies a latest previous version (there may be
more than one in case of merges) of the artifact the event represents.
required: false
multiple: true
targets:
any_type: false
types:
- EiffelArtifactCreatedEvent
_history:
- version: 3.3.0
introduced_in: No edition set
changes: Added data.fileInformation.integrityProtection member (see [Issue 290](https://github.com/eiffel-community/eiffel/issues/290)).
- version: 3.2.0
introduced_in: 'No edition set'
changes: Add schema URL to the meta object (see [Issue 280](https://github.com/eiffel-community/eiffel/issues/280)).
- version: 3.1.0
introduced_in: '[edition-lyon](../../../tree/edition-lyon)'
changes: Add links.domainId member (see [Issue 233](https://github.com/eiffel-community/eiffel/issues/233)).
- version: 3.0.0
introduced_in: '[edition-agen](../../../tree/edition-agen)'
changes: Improved information integrity protection (see [Issue
185](https://github.com/eiffel-community/eiffel/issues/185)).
- version: 2.0.0
introduced_in: '[dc5ec6f](../../../blob/dc5ec6fb87e293eeffe88fdafe698eec0f5a2c89/eiffel-vocabulary/EiffelArtifactCreatedEvent.md)'
changes: Introduced purl identifiers instead of GAVs (see [Issue
182](https://github.com/eiffel-community/eiffel/issues/182))
- version: 1.1.0
introduced_in: '[edition-toulouse](../../../tree/edition-toulouse)'
changes: Multiple links of type FLOW_CONTEXT allowed.
- version: 1.0.0
introduced_in: '[edition-bordeaux](../../../tree/edition-bordeaux)'
changes: Initial version.
_examples:
- title: Simple example
url: ../examples/events/EiffelArtifactCreatedEvent/simple.json
- title: Interface example
url: ../examples/events/EiffelArtifactCreatedEvent/interface.json
- title: Backend example
url: ../examples/events/EiffelArtifactCreatedEvent/backend.json
- title: Dependent example
url: ../examples/events/EiffelArtifactCreatedEvent/dependent.json
- title: Checksum example
url: ../examples/events/EiffelArtifactCreatedEvent/checksum.json
11 changes: 9 additions & 2 deletions eiffel-syntax-and-usage/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ Let us begin by establishing that the Eiffel protocol by itself can be considere
In the words of ISO27000, confidentiality means that "information is not made available or disclosed to unauthorized individuals, entities, or processes". This can be achieved through multiple (and often complementary) means, such as encryption and access control. The Eiffel protocol itself cannot support confidentiality; instead it is a property of the systems used to transport, process and store the Eiffel events. In other words, if the confidentiality of information communicated as Eiffel events is a concern for you, then you are recommended to take appropriate action to ensure the confidentiality of your data, both at rest and in transit, e.g. through encryption.

## Integrity
In information security, integrity refers to the accuracy and completeness of data. In other words, safeguarding integrity requires protection against both malicious and unintentional tampering with or corruption of data in an unauthorized or undetected manner. This cannot be _solved_ by a communication protocol, as it relies on adequate infrastructure and processes for managing the data, but it can be _supported_. Eiffel supports data integrity through digital signatures.

A digital signature is a combination of hashing technology and encryption. Hash functions are commonly used to ensure data integrity and are familiar to most software professionals. By using checksums or hash values (particularly hash values, or _digests_, produced by cryptographic hash functions such as the SHA series), any piece of data of arbitrary length is computed into a fixed length digest, with any alteration of the input data resulting in a different digest. Consequently, as long as the digest of the received data matches the digest of the data sent, its integrity can be verified. Unfortunately, the digest must be securely communicated: any malicious attacker able to not only manipulate the data but also the digest can make a corrupted message appear authentic. This is why digital signing also employs encryption.
In information security, integrity refers to the accuracy and completeness of data. In other words, safeguarding integrity requires protection against both malicious and unintentional tampering with or corruption of data in an unauthorized or undetected manner. This cannot be _solved_ by a communication protocol, as it relies on adequate infrastructure and processes for managing the data, but it can be _supported_. Eiffel supports two aspects of data integrity; integrity of event payloads and integrity of referenced items.

### Integrity of event payloads

The integrity of the contents of an Eiffel event, i.e. its payload, can be protected via a digital signature. A digital signature is a combination of hashing technology and encryption. Hash functions are commonly used to ensure data integrity and are familiar to most software professionals. By using checksums or hash values (particularly hash values, or _digests_, produced by cryptographic hash functions such as the SHA series), any piece of data of arbitrary length is computed into a fixed length digest, with any alteration of the input data resulting in a different digest. Consequently, as long as the digest of the received data matches the digest of the data sent, its integrity can be verified. Unfortunately, the digest must be securely communicated: any malicious attacker able to not only manipulate the data but also the digest can make a corrupted message appear authentic. This is why digital signing also employs encryption.

The Eiffel protocol's support is influenced by [JSON Web Signatures (JWS)](https://tools.ietf.org/html/rfc7515), with slight modifications to allow inclusion of the signature within the event message itself, rather than as part of a header. This serves to keep every Eiffel event self-contained, with information integrity protection optional for the producer to include and optional for the consumer to consider. Note that this optionality does not in any way lessen the strength of the security provided: it is always up to the recipient of an unprotected Eiffel event to decide whether to trust it or not. In this sense, Eiffel support of data integrity is very similar to that employed by other document formats, such as the [Portable Document Format](http://www.adobe.com/devnet/pdf/pdf_reference.html).

Apart from digital signing, the Eiffel protocol also supports author identification using [Distinguished Names](https://tools.ietf.org/html/rfc2253) and event sequence integrity protection. Please see the documentation of each event type for further information and detailed instructions on correct usage.

### Integrity of referenced items

Some Eiffel events reference external data whose integrity is important to track, e.g. the files that make up an artifact. In this case a cryptographic digest of the data is stored in the Eiffel event, allowing event consumers to verify that the data hasn't been modified by either an honest mistake, corruption, or malicious intent. The use of such a digest may be combined with a digital signature of the event to secure the integrity of the digest.

## Availability
Availability of information communicated over the Eiffel protocol is a property of the communication channels and storage solutions used. In other words, similarly to confidentiality, it is an infrastructural concern and external to the protocol itself.
22 changes: 21 additions & 1 deletion eiffel-vocabulary/EiffelArtifactCreatedEvent.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!---
This file was generated from ../definitions/EiffelArtifactCreatedEvent/3.2.0.yml.
This file was generated from ../definitions/EiffelArtifactCreatedEvent/3.3.0.yml.
See that file for a copyright notice.
--->

Expand Down Expand Up @@ -29,6 +29,24 @@ __Type:__ String[]
__Required:__ No
__Description:__ Any tags associated with the file, to support navigation and identification of items of interest.

#### data.fileInformation.integrityProtection
__Type:__ Object
__Required:__ No
__Description:__ An optional object containing a digest of the file's contents, i.e. a checksum, computed using the specified algorithm.

##### data.fileInformation.integrityProtection.alg
__Type:__ String
__Format:__ One of the hash algorithms listed in section 1 of [NIST FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf), excluding "SHA-1".
__Required:__ Yes
__Legal values:__ SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256
__Description:__ The cryptographic algorithm used to compute the digest of the file's contents.

##### data.fileInformation.integrityProtection.digest
__Type:__ String
__Format:__ A lowercase string of hexadecimal digits.
__Required:__ Yes
__Description:__ The digest of the file contents.

### data.buildCommand
__Type:__ String
__Required:__ No
Expand Down Expand Up @@ -235,6 +253,7 @@ __Description:__ A URI pointing at a location from where the schema used when cr

| Version | Introduced in | Changes |
| ------- | ------------- | ------- |
| 3.3.0 | No edition set | Added data.fileInformation.integrityProtection member (see [Issue 290](https://github.com/eiffel-community/eiffel/issues/290)). |
| 3.2.0 | No edition set | Add schema URL to the meta object (see [Issue 280](https://github.com/eiffel-community/eiffel/issues/280)). |
| 3.1.0 | [edition-lyon](../../../tree/edition-lyon) | Add links.domainId member (see [Issue 233](https://github.com/eiffel-community/eiffel/issues/233)). |
| 3.0.0 | [edition-agen](../../../tree/edition-agen) | Improved information integrity protection (see [Issue 185](https://github.com/eiffel-community/eiffel/issues/185)). |
Expand All @@ -249,3 +268,4 @@ __Description:__ A URI pointing at a location from where the schema used when cr
* [Interface example](../examples/events/EiffelArtifactCreatedEvent/interface.json)
* [Backend example](../examples/events/EiffelArtifactCreatedEvent/backend.json)
* [Dependent example](../examples/events/EiffelArtifactCreatedEvent/dependent.json)
* [Checksum example](../examples/events/EiffelArtifactCreatedEvent/checksum.json)
31 changes: 31 additions & 0 deletions examples/events/EiffelArtifactCreatedEvent/checksum.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"meta": {
"type": "EiffelArtifactCreatedEvent",
"version": "3.3.0",
"time": 1234567890,
"id": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee0"
},
"data": {
"identity": "pkg:generic/empty-file",
"fileInformation": [
{
"name": "empty-file.txt",
"integrityProtection": {
"alg": "SHA-256",
"digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
}
],
"name": "This artifact is just an empty file"
},
"links": [
{
"type": "CAUSE",
"target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
},
{
"type": "COMPOSITION",
"target": "aaaaaaaa-bbbb-5ccc-8ddd-eeeeeeeeeee1"
}
]
}

0 comments on commit aafb9ec

Please sign in to comment.