Skip to content

Commit

Permalink
Machinery for singing generic manifests.
Browse files Browse the repository at this point in the history
THIS IS DRAFT, WIP. Will split into separate PRs once it works. But
posting publicly to show what the plans are (sigstore#224, sigstore#248, sigstore#240, sigstore#111).

Signed-off-by: Mihai Maruseac <mihaimaruseac@google.com>
  • Loading branch information
mihaimaruseac committed Jul 24, 2024
1 parent 0c7d34c commit d3d4cce
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
pip install -r model_signing/install/requirements_test_Linux.txt
pip install -r model_signing/install/requirements_dev_Linux.txt
# TODO: https://github.com/sigstore/model-transparency/issues/231 - Support all repo
pytype --keep-going model_signing/{hashing,manifest,serialization}
pytype --keep-going model_signing/{hashing,manifest,serialization,signing}
pylint-lint:
runs-on: ubuntu-latest
Expand All @@ -85,4 +85,4 @@ jobs:
pip install -r model_signing/install/requirements_dev_Linux.txt
# TODO: https://github.com/sigstore/model-transparency/issues/231 - Support all repo
# We should actually migrate to ruff, but that's configured via pyproject.toml which we use when we release the wheel
pylint --disable C0114,C0115,C0116,R0801,R0903,R0904,R0913,R0914,R1721,R1737,W0107,W0212,W0223,W0231,W0511,W0621 model_signing/{hashing,manifest,serialization}
pylint --disable C0114,C0115,C0116,R0801,R0903,R0904,R0913,R0914,R1721,R1737,W0107,W0212,W0223,W0231,W0511,W0621 model_signing/{hashing,manifest,serialization,signing}
13 changes: 13 additions & 0 deletions model_signing/signing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2024 The Sigstore Authors
#
# 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.
80 changes: 80 additions & 0 deletions model_signing/signing/signing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright 2024 The Sigstore Authors
#
# 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.

"""Machinery for signing and verification of ML models.
The serialization API produces a manifest representation of the models, which
can be used to implement various verification patterns. However, when signing,
we need to actually represent this manifest in a specific disk format. But,
there are multiple ways to use `manifest.Manifest` objects, so we add a new
`SigningMaterial` class hierarchy to serialize and sign manifests.
The output of a signing process is a `Signature` instance, backed by a format to
serialize this to disk. In OSS, this is usually a Sigstore bundle.
TODO: expand on this.
"""

import abc
import pathlib
from typing import Self

from model_signing.manifest import manifest


class SigningMaterial(metaclass=abc.ABCMeta):
"""Generic material that we can sign."""

@classmethod
@abc.abstractmethod
def from_manifest(cls, manifest: manifest.Manifest) -> Self:
"""Converts a manifest to the signing material used for signing."""
pass

@abc.abstractmethod
def sign(self) -> "Signature":
"""Signs the current SigningMaterial with the provided key/signer.
TODO: arguments, abstract over signing format, etc.
"""
pass


class Signature(metaclass=abc.ABCMeta):
"""Generic signature support."""

@abc.abstractmethod
def write_signature(self, path: pathlib.Path):
"""Writes the signature to disk, to the given path."""
pass

@classmethod
@abc.abstractmethod
def read_signature(cls, path: pathlib.Path) -> Self:
"""Reads the signature from disk.
Does not perform any verification, except what is needed to parse the
signature file. Use `verify` to validate the signature.
"""
pass

@abc.abstractmethod
def verify(self): # TODO: signature
"""Verifies the signature.
If the verification passes, this method returns TODO: what?
TODO: Document return and raises.
"""
pass
19 changes: 19 additions & 0 deletions model_signing/test_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@
]


# All directory models to use in testing, where only non empty directory models
# are supported. See also `all_test_models` comments.
all_non_empty_directory_test_models = [
"sample_model_folder",
"deep_model_folder",
"model_folder_with_empty_file",
"symlink_model_folder",
]


# All directory models to use in testing, where only non empty directory models
# are supported. See also `all_test_models` comments.
all_non_empty_directory_test_models = [
"sample_model_folder",
"deep_model_folder",
"model_folder_with_empty_file",
]


def get_first_directory(path: pathlib.Path) -> pathlib.Path:
"""Returns the first directory that is a children of path.
Expand Down

0 comments on commit d3d4cce

Please sign in to comment.