From aab669acc615ccb55cedcaa6ef1847ebcc5be484 Mon Sep 17 00:00:00 2001
From: Juliette Pretot <julsh@google.com>
Date: Wed, 17 Jan 2024 18:33:41 +0000
Subject: [PATCH 1/7] Consolidate oak containers protos into one file customer
 teams, and add helpful build targets

---
 Cargo.lock                                    |  2 -
 oak_containers/README.md                      |  5 ---
 oak_containers_launcher/build.rs              |  2 +-
 oak_containers_launcher/src/lib.rs            |  2 -
 oak_containers_launcher/src/server.rs         | 12 ++----
 oak_containers_orchestrator/build.rs          |  4 +-
 oak_containers_orchestrator/src/ipc_server.rs |  4 +-
 .../src/launcher_client.rs                    |  6 +--
 oak_containers_orchestrator/src/lib.rs        |  2 -
 oak_containers_sdk/Cargo.toml                 |  1 -
 oak_containers_sdk/build.rs                   |  3 +-
 oak_containers_sdk/src/lib.rs                 |  2 -
 oak_containers_sdk/src/orchestrator_client.rs |  2 +-
 oak_containers_stage1/Cargo.toml              |  1 -
 oak_containers_stage1/build.rs                |  2 +-
 oak_containers_stage1/src/client.rs           |  7 +++-
 oak_functions_containers_app/build.rs         |  3 +-
 oak_functions_containers_app/src/lib.rs       |  6 ++-
 proto/containers/BUILD                        | 42 +++++++++++++++++--
 ...pto.proto => application_interfaces.proto} | 16 +++++++
 .../build.rs => proto/containers/common.proto | 19 +++------
 .../containers/launcher.proto                 | 23 ++--------
 22 files changed, 90 insertions(+), 76 deletions(-)
 delete mode 100644 oak_containers/README.md
 rename proto/containers/{orchestrator_crypto.proto => application_interfaces.proto} (74%)
 rename oak_containers_syslogd/build.rs => proto/containers/common.proto (58%)
 rename oak_containers/proto/interfaces.proto => proto/containers/launcher.proto (74%)

diff --git a/Cargo.lock b/Cargo.lock
index 1bda7f49834..0ab1e7986bc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2035,7 +2035,6 @@ dependencies = [
  "anyhow",
  "async-stream",
  "async-trait",
- "oak_attestation",
  "oak_crypto",
  "oak_grpc_utils",
  "prost",
@@ -2057,7 +2056,6 @@ dependencies = [
  "futures-util",
  "nix 0.27.1",
  "oak_attestation",
- "oak_crypto",
  "oak_dice",
  "oak_grpc_utils",
  "p256",
diff --git a/oak_containers/README.md b/oak_containers/README.md
deleted file mode 100644
index 271d7e3384e..00000000000
--- a/oak_containers/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-<!-- Oak Logo Start -->
-<!-- An HTML element is intentionally used since GitHub recommends this approach to handle different images in dark/light modes. Ref: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#specifying-the-theme-an-image-is-shown-to -->
-<!-- markdownlint-disable-next-line MD033 -->
-<h1><picture><source media="(prefers-color-scheme: dark)" srcset="/docs/oak-logo/svgs/oak-containers-negative-colour.svg?sanitize=true"><source media="(prefers-color-scheme: light)" srcset="/docs/oak-logo/svgs/oak-containers.svg?sanitize=true"><img alt="Project Oak Containers Logo" src="/docs/oak-logo/svgs/oak-containers.svg?sanitize=true"></picture></h1>
-<!-- Oak Logo End -->
diff --git a/oak_containers_launcher/build.rs b/oak_containers_launcher/build.rs
index 6ab1f018814..75643f832c5 100644
--- a/oak_containers_launcher/build.rs
+++ b/oak_containers_launcher/build.rs
@@ -19,7 +19,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     // Generate gRPC code for connecting to the launcher.
     generate_grpc_code(
         &[
-            "../oak_containers/proto/interfaces.proto",
+            "../proto/containers/launcher.proto",
             "../oak_crypto/proto/v1/crypto.proto",
             "../proto/key_provisioning/key_provisioning.proto",
             "../proto/containers/hostlib_key_provisioning.proto",
diff --git a/oak_containers_launcher/src/lib.rs b/oak_containers_launcher/src/lib.rs
index e1d2ee95c91..dac85c5197e 100644
--- a/oak_containers_launcher/src/lib.rs
+++ b/oak_containers_launcher/src/lib.rs
@@ -16,8 +16,6 @@
 pub mod proto {
     pub mod oak {
         pub mod containers {
-            #![allow(clippy::return_self_not_must_use)]
-            tonic::include_proto!("oak.containers");
             pub mod v1 {
                 #![allow(clippy::return_self_not_must_use)]
                 tonic::include_proto!("oak.containers.v1");
diff --git a/oak_containers_launcher/src/server.rs b/oak_containers_launcher/src/server.rs
index 2ff49e1b51b..d0871619fbf 100644
--- a/oak_containers_launcher/src/server.rs
+++ b/oak_containers_launcher/src/server.rs
@@ -43,15 +43,11 @@ use tokio_stream::wrappers::TcpListenerStream;
 use tonic::{transport::Server, Request, Response, Status};
 
 use crate::proto::oak::{
-    containers::{
+    containers::v1::{
+        hostlib_key_provisioning_server::{HostlibKeyProvisioning, HostlibKeyProvisioningServer},
         launcher_server::{Launcher, LauncherServer},
-        v1::{
-            hostlib_key_provisioning_server::{
-                HostlibKeyProvisioning, HostlibKeyProvisioningServer,
-            },
-            GetGroupKeysResponse, GetKeyProvisioningRoleResponse, KeyProvisioningRole,
-        },
-        GetApplicationConfigResponse, GetImageResponse, SendAttestationEvidenceRequest,
+        GetApplicationConfigResponse, GetGroupKeysResponse, GetImageResponse,
+        GetKeyProvisioningRoleResponse, KeyProvisioningRole, SendAttestationEvidenceRequest,
     },
     session::v1::AttestationEvidence,
 };
diff --git a/oak_containers_orchestrator/build.rs b/oak_containers_orchestrator/build.rs
index 888e1c210e4..a1d7c579f95 100644
--- a/oak_containers_orchestrator/build.rs
+++ b/oak_containers_orchestrator/build.rs
@@ -19,9 +19,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     // Generate gRPC code for Orchestrator services.
     generate_grpc_code(
         &[
-            "../oak_containers/proto/interfaces.proto",
             "../proto/key_provisioning/key_provisioning.proto",
-            "../proto/containers/orchestrator_crypto.proto",
+            "../proto/containers/application_interfaces.proto",
+            "../proto/containers/launcher.proto",
             "../proto/containers/hostlib_key_provisioning.proto",
             "../proto/session/messages.proto",
         ],
diff --git a/oak_containers_orchestrator/src/ipc_server.rs b/oak_containers_orchestrator/src/ipc_server.rs
index a37dbdab918..ff2222bb9a1 100644
--- a/oak_containers_orchestrator/src/ipc_server.rs
+++ b/oak_containers_orchestrator/src/ipc_server.rs
@@ -24,9 +24,9 @@ use tonic::{transport::Server, Request, Response};
 use crate::{
     crypto::{CryptoService, KeyStore},
     launcher_client::LauncherClient,
-    proto::oak::containers::{
+    proto::oak::containers::v1::{
+        orchestrator_crypto_server::OrchestratorCryptoServer,
         orchestrator_server::{Orchestrator, OrchestratorServer},
-        v1::orchestrator_crypto_server::OrchestratorCryptoServer,
         GetApplicationConfigResponse,
     },
 };
diff --git a/oak_containers_orchestrator/src/launcher_client.rs b/oak_containers_orchestrator/src/launcher_client.rs
index 6eb26ad1319..9cf85974e79 100644
--- a/oak_containers_orchestrator/src/launcher_client.rs
+++ b/oak_containers_orchestrator/src/launcher_client.rs
@@ -19,9 +19,9 @@ use tonic::transport::Channel;
 
 use crate::proto::oak::{
     attestation::v1::Evidence,
-    containers::{
-        launcher_client::LauncherClient as GrpcLauncherClient,
-        v1::{hostlib_key_provisioning_client::HostlibKeyProvisioningClient, KeyProvisioningRole},
+    containers::v1::{
+        hostlib_key_provisioning_client::HostlibKeyProvisioningClient,
+        launcher_client::LauncherClient as GrpcLauncherClient, KeyProvisioningRole,
         SendAttestationEvidenceRequest,
     },
     key_provisioning::v1::GroupKeys,
diff --git a/oak_containers_orchestrator/src/lib.rs b/oak_containers_orchestrator/src/lib.rs
index 90a5bd59fa0..82e358237c0 100644
--- a/oak_containers_orchestrator/src/lib.rs
+++ b/oak_containers_orchestrator/src/lib.rs
@@ -16,8 +16,6 @@
 pub mod proto {
     pub mod oak {
         pub mod containers {
-            #![allow(clippy::return_self_not_must_use)]
-            tonic::include_proto!("oak.containers");
             pub mod v1 {
                 #![allow(clippy::return_self_not_must_use)]
                 tonic::include_proto!("oak.containers.v1");
diff --git a/oak_containers_sdk/Cargo.toml b/oak_containers_sdk/Cargo.toml
index 0824a8b39c5..3d033853178 100644
--- a/oak_containers_sdk/Cargo.toml
+++ b/oak_containers_sdk/Cargo.toml
@@ -11,7 +11,6 @@ oak_grpc_utils = { workspace = true }
 [dependencies]
 anyhow = "*"
 async-trait = { version = "*", default-features = false }
-oak_attestation = { workspace = true }
 oak_crypto = { workspace = true }
 prost = "*"
 prost-types = "*"
diff --git a/oak_containers_sdk/build.rs b/oak_containers_sdk/build.rs
index 4c27e7685a0..c1d3562ee3a 100644
--- a/oak_containers_sdk/build.rs
+++ b/oak_containers_sdk/build.rs
@@ -19,10 +19,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     // Generate gRPC code for connecting to the Orchestrator.
     generate_grpc_code(
         &[
-            "oak_containers/proto/interfaces.proto",
             "oak_crypto/proto/v1/crypto.proto",
             "proto/session/messages.proto",
-            "proto/containers/orchestrator_crypto.proto",
+            "proto/containers/application_interfaces.proto",
         ],
         "..",
         CodegenOptions {
diff --git a/oak_containers_sdk/src/lib.rs b/oak_containers_sdk/src/lib.rs
index ac176c72b7a..86db8d6dec7 100644
--- a/oak_containers_sdk/src/lib.rs
+++ b/oak_containers_sdk/src/lib.rs
@@ -16,13 +16,11 @@
 mod proto {
     pub mod oak {
         pub mod containers {
-            tonic::include_proto!("oak.containers");
             pub mod v1 {
                 #![allow(clippy::return_self_not_must_use)]
                 tonic::include_proto!("oak.containers.v1");
             }
         }
-        pub use oak_attestation::proto::oak::{attestation, session};
         pub use oak_crypto::proto::oak::crypto;
     }
 }
diff --git a/oak_containers_sdk/src/orchestrator_client.rs b/oak_containers_sdk/src/orchestrator_client.rs
index dfd91f39d1d..a3a785b9d7a 100644
--- a/oak_containers_sdk/src/orchestrator_client.rs
+++ b/oak_containers_sdk/src/orchestrator_client.rs
@@ -17,7 +17,7 @@ use anyhow::{Context, Result};
 use tonic::transport::{Endpoint, Uri};
 use tower::service_fn;
 
-use crate::proto::oak::containers::orchestrator_client::OrchestratorClient as GrpcOrchestratorClient;
+use crate::proto::oak::containers::v1::orchestrator_client::OrchestratorClient as GrpcOrchestratorClient;
 
 // Unix Domain Sockets do not use URIs, hence this URI will never be used.
 // It is defined purely since in order to create a channel, since a URI has to
diff --git a/oak_containers_stage1/Cargo.toml b/oak_containers_stage1/Cargo.toml
index 1acc045a2cb..1778412b06b 100644
--- a/oak_containers_stage1/Cargo.toml
+++ b/oak_containers_stage1/Cargo.toml
@@ -15,7 +15,6 @@ clap = { version = "*", features = ["derive"] }
 coset = { version = "*", features = ["std"] }
 futures-util = "*"
 oak_attestation = { workspace = true }
-oak_crypto = { workspace = true }
 oak_dice = { workspace = true }
 nix = { version = "*", features = ["mman"] }
 p256 = { version = "*" }
diff --git a/oak_containers_stage1/build.rs b/oak_containers_stage1/build.rs
index db121450dc6..f1bbabe20d1 100644
--- a/oak_containers_stage1/build.rs
+++ b/oak_containers_stage1/build.rs
@@ -20,9 +20,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     // Generate gRPC code for loading the system image.
     generate_grpc_code(
         &[
-            "../oak_containers/proto/interfaces.proto",
             "../oak_crypto/proto/v1/crypto.proto",
             "../proto/session/messages.proto",
+            "../proto/containers/launcher.proto",
         ],
         "..",
         CodegenOptions {
diff --git a/oak_containers_stage1/src/client.rs b/oak_containers_stage1/src/client.rs
index fdebe741a1d..3ed9486d00f 100644
--- a/oak_containers_stage1/src/client.rs
+++ b/oak_containers_stage1/src/client.rs
@@ -17,14 +17,17 @@
 mod proto {
     pub mod oak {
         pub mod containers {
-            tonic::include_proto!("oak.containers");
+            pub mod v1 {
+                #![allow(clippy::return_self_not_must_use)]
+                tonic::include_proto!("oak.containers.v1");
+            }
         }
         pub use oak_attestation::proto::oak::{attestation, session};
     }
 }
 
 use anyhow::{Context, Result};
-use proto::oak::containers::launcher_client::LauncherClient as GrpcLauncherClient;
+use proto::oak::containers::v1::launcher_client::LauncherClient as GrpcLauncherClient;
 use tonic::transport::{Channel, Uri};
 
 pub struct LauncherClient {
diff --git a/oak_functions_containers_app/build.rs b/oak_functions_containers_app/build.rs
index 955a9e2cbe9..4dd125fb5af 100644
--- a/oak_functions_containers_app/build.rs
+++ b/oak_functions_containers_app/build.rs
@@ -38,7 +38,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     generate_grpc_code(
         &[
-            "../oak_containers/proto/interfaces.proto",
+            "../oak_crypto/proto/v1/crypto.proto",
+            "../proto/containers/application_interfaces.proto",
             "../proto/session/messages.proto",
         ],
         "..",
diff --git a/oak_functions_containers_app/src/lib.rs b/oak_functions_containers_app/src/lib.rs
index fc3272c517f..b809725a22a 100644
--- a/oak_functions_containers_app/src/lib.rs
+++ b/oak_functions_containers_app/src/lib.rs
@@ -52,8 +52,10 @@ pub mod proto {
             tonic::include_proto!("oak.functions");
         }
         pub mod containers {
-            #![allow(clippy::return_self_not_must_use)]
-            tonic::include_proto!("oak.containers");
+            pub mod v1 {
+                #![allow(clippy::return_self_not_must_use)]
+                tonic::include_proto!("oak.containers.v1");
+            }
         }
         pub use oak_attestation::proto::oak::{attestation, session};
         pub use oak_crypto::proto::oak::crypto;
diff --git a/proto/containers/BUILD b/proto/containers/BUILD
index 3a61fa305e6..1345cbe2a37 100644
--- a/proto/containers/BUILD
+++ b/proto/containers/BUILD
@@ -16,6 +16,8 @@
 
 load("@bazel_skylib//rules:build_test.bzl", "build_test")
 load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
 
 package(
     default_visibility = ["//visibility:public"],
@@ -23,10 +25,43 @@ package(
 )
 
 proto_library(
-    name = "orchestrator_crypto_proto",
-    srcs = ["orchestrator_crypto.proto"],
+    name = "common_proto",
+    srcs = ["common.proto"],
+)
+
+proto_library(
+    name = "application_interfaces_proto",
+    srcs = ["application_interfaces.proto"],
     deps = [
         "//oak_crypto/proto/v1:crypto_proto",
+        "//oak_remote_attestation/proto/v1:messages_proto",
+        "@com_google_protobuf//:empty_proto",
+        ":common_proto"
+    ],
+)
+
+cc_proto_library(
+    name = "application_interfaces_cc_proto",
+    deps = [":application_interfaces_proto"],
+)
+
+
+py_proto_library(
+    name = "application_interfaces_py_proto",
+    deps = [":application_interfaces_proto"],
+)
+
+py_grpc_library(
+    name = "application_interfaces_py_grpc",
+    srcs = [":application_interfaces_proto"],
+    deps = [":application_interfaces_py_proto"],
+)
+
+proto_library(
+    name = "launcher_proto",
+    srcs = ["launcher.proto"],
+    deps = [
+        ":common_proto",
     ],
 )
 
@@ -42,6 +77,7 @@ build_test(
     name = "build_test",
     targets = [
         ":hostlib_key_provisioning_proto",
-        ":orchestrator_crypto_proto",
+        ":application_interfaces_proto",
+        ":launcher_proto"
     ],
 )
diff --git a/proto/containers/orchestrator_crypto.proto b/proto/containers/application_interfaces.proto
similarity index 74%
rename from proto/containers/orchestrator_crypto.proto
rename to proto/containers/application_interfaces.proto
index 3e881f56f35..aee61cf3553 100644
--- a/proto/containers/orchestrator_crypto.proto
+++ b/proto/containers/application_interfaces.proto
@@ -14,11 +14,27 @@
 // limitations under the License.
 //
 
+// Interfaces that may be invoked by the application
+
 syntax = "proto3";
 
 package oak.containers.v1;
 
 import "oak_crypto/proto/v1/crypto.proto";
+import "google/protobuf/empty.proto";
+import "proto/containers/common.proto";
+
+// Defines the service exposed by the orchestrator, that can be invoked by the application.
+service Orchestrator {
+  // Exposes the previously loaded trusted application config to the application,
+  // which may choose to retrieve it.
+  rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {}
+
+  // Notifies the orchestrator that the trusted app is ready to serve requests and listening on the
+  // pre-arranged port (8080).
+  rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
+}
+
 
 // Choice between a key generated by the enclave instance and the key distributed to the enclave
 // group with Key Provisioning.
diff --git a/oak_containers_syslogd/build.rs b/proto/containers/common.proto
similarity index 58%
rename from oak_containers_syslogd/build.rs
rename to proto/containers/common.proto
index b24dee1632e..9a688abe789 100644
--- a/oak_containers_syslogd/build.rs
+++ b/proto/containers/common.proto
@@ -14,19 +14,12 @@
 // limitations under the License.
 //
 
-use oak_grpc_utils::{generate_grpc_code, CodegenOptions};
+syntax = "proto3";
 
-fn main() -> Result<(), Box<dyn std::error::Error>> {
-    // Generate gRPC code for connecting to the launcher.
-    generate_grpc_code(
-        &[
-            "../oak_containers/proto/interfaces.proto",
-            "../oak_crypto/proto/v1/crypto.proto",
-            "../proto/session/messages.proto",
-        ],
-        "..",
-        CodegenOptions::default(),
-    )?;
+package oak.containers.v1;
 
-    Ok(())
+message GetApplicationConfigResponse {
+  // Arbitrary config that the container can retrieve from the orchestrator.
+  // Included in the attestation measurements conducted by the orchestrator.
+  bytes config = 1;
 }
diff --git a/oak_containers/proto/interfaces.proto b/proto/containers/launcher.proto
similarity index 74%
rename from oak_containers/proto/interfaces.proto
rename to proto/containers/launcher.proto
index 35a0ea19f81..2c84830d37f 100644
--- a/oak_containers/proto/interfaces.proto
+++ b/proto/containers/launcher.proto
@@ -16,13 +16,13 @@
 
 syntax = "proto3";
 
-package oak.containers;
+package oak.containers.v1;
 
 import "google/protobuf/empty.proto";
-import "oak_crypto/proto/v1/crypto.proto";
-import "proto/attestation/endorsement.proto";
 import "proto/attestation/evidence.proto";
 import "proto/session/messages.proto";
+import "proto/containers/common.proto";
+
 
 // As images can be large (hundreds of megabytes), the launcher chunks up the response into smaller
 // pieces to respect proto/gRPC limits. The image needs to be reassembled in the stage1 or the
@@ -31,12 +31,6 @@ message GetImageResponse {
   bytes image_chunk = 1;
 }
 
-message GetApplicationConfigResponse {
-  // Arbitrary config that the container can retrieve from the orchestrator.
-  // Included in the attestation measurements conducted by the orchestrator.
-  bytes config = 1;
-}
-
 message SendAttestationEvidenceRequest {
   oak.session.v1.AttestationEvidence evidence = 1 [deprecated = true];
   oak.attestation.v1.Evidence dice_evidence = 2;
@@ -67,14 +61,3 @@ service Launcher {
   // pre-arranged port (8080).
   rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
 }
-
-// Defines the service exposed by the orchestrator, that can be invoked by the application.
-service Orchestrator {
-  // Exposes the previously loaded trusted application config to the application,
-  // which may choose to retrieve it.
-  rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {}
-
-  // Notifies the orchestrator that the trusted app is ready to serve requests and listening on the
-  // pre-arranged port (8080).
-  rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
-}

From e4ac9aa1ac02b1c5714036f4cf2d40c7f93c09e1 Mon Sep 17 00:00:00 2001
From: Juliette Pretot <julsh@google.com>
Date: Wed, 17 Jan 2024 18:46:08 +0000
Subject: [PATCH 2/7] add cc grpc build target

---
 proto/containers/BUILD | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/proto/containers/BUILD b/proto/containers/BUILD
index 1345cbe2a37..0471cfa59d0 100644
--- a/proto/containers/BUILD
+++ b/proto/containers/BUILD
@@ -17,6 +17,7 @@
 load("@bazel_skylib//rules:build_test.bzl", "build_test")
 load("@rules_proto//proto:defs.bzl", "proto_library")
 load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
 load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
 
 package(
@@ -45,6 +46,13 @@ cc_proto_library(
     deps = [":application_interfaces_proto"],
 )
 
+cc_grpc_library(
+    name = "application_interfaces_cc_grpc",
+    srcs = [":application_interfaces_proto"],
+    grpc_only = True,
+    deps = [":application_interfaces_proto"],
+)
+
 
 py_proto_library(
     name = "application_interfaces_py_proto",

From 3a823575cebd9291beebb08b3236ba3a12d90eb1 Mon Sep 17 00:00:00 2001
From: Juliette Pretot <julsh@google.com>
Date: Wed, 17 Jan 2024 20:19:18 +0000
Subject: [PATCH 3/7] Preserve existing proto files, so the change is not
 considered blocking

---
 oak_containers/proto/interfaces.proto      | 84 ++++++++++++++++++++++
 proto/containers/BUILD                     |  9 +++
 proto/containers/orchestrator_crypto.proto | 64 +++++++++++++++++
 3 files changed, 157 insertions(+)
 create mode 100644 oak_containers/proto/interfaces.proto
 create mode 100644 proto/containers/orchestrator_crypto.proto

diff --git a/oak_containers/proto/interfaces.proto b/oak_containers/proto/interfaces.proto
new file mode 100644
index 00000000000..d886a43dac7
--- /dev/null
+++ b/oak_containers/proto/interfaces.proto
@@ -0,0 +1,84 @@
+//
+// Copyright 2023 The Project Oak 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.
+//
+
+syntax = "proto3";
+
+// TODO(#4392): Remove this file once the migration is complete.
+// This file is deprecated. The relevant functionality is available in `proto/containers/application_interfaces.proto` & `proto/containers/launcher.proto`.
+// DO NOT MODIFY THIS FILE, DO NOT ADD NEW DEPENDENCIES ON IT.
+
+package oak.containers;
+
+import "google/protobuf/empty.proto";
+import "oak_crypto/proto/v1/crypto.proto";
+import "proto/attestation/endorsement.proto";
+import "proto/attestation/evidence.proto";
+import "proto/session/messages.proto";
+
+// As images can be large (hundreds of megabytes), the launcher chunks up the response into smaller
+// pieces to respect proto/gRPC limits. The image needs to be reassembled in the stage1 or the
+// orchestrator.
+message GetImageResponse {
+  bytes image_chunk = 1;
+}
+
+message GetApplicationConfigResponse {
+  // Arbitrary config that the container can retrieve from the orchestrator.
+  // Included in the attestation measurements conducted by the orchestrator.
+  bytes config = 1;
+}
+
+message SendAttestationEvidenceRequest {
+  oak.session.v1.AttestationEvidence evidence = 1 [deprecated = true];
+  oak.attestation.v1.Evidence dice_evidence = 2;
+}
+
+// Defines the service exposed by the launcher, that can be invoked by the stage1 and the
+// orchestrator.
+service Launcher {
+  // Provides stage1 with the Oak system image (which contains the Linux distribution and the
+  // orchestrator binary).
+  rpc GetOakSystemImage(google.protobuf.Empty) returns (stream GetImageResponse) {}
+
+  // Provides orchestrator with the trusted container image.
+  rpc GetContainerBundle(google.protobuf.Empty) returns (stream GetImageResponse) {}
+
+  // This method is used by the orchestrator to load and measure the trusted
+  // application config. The orchestrator will later, separately expose this
+  // config to the application.
+  rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {}
+
+  // Sends Attestation Evidence containing the Attestation Report with corresponding measurements
+  // and public keys to the Launcher.
+  // This API is called exactly once after the Attestation Evidence is generated. Calling this API
+  // a second time will result in an error.
+  rpc SendAttestationEvidence(SendAttestationEvidenceRequest) returns (google.protobuf.Empty) {}
+
+  // Notifies the launcher that the trusted app is ready to serve requests and listening on the
+  // pre-arranged port (8080).
+  rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
+}
+
+// Defines the service exposed by the orchestrator, that can be invoked by the application.
+service Orchestrator {
+  // Exposes the previously loaded trusted application config to the application,
+  // which may choose to retrieve it.
+  rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {}
+
+  // Notifies the orchestrator that the trusted app is ready to serve requests and listening on the
+  // pre-arranged port (8080).
+  rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
+}
diff --git a/proto/containers/BUILD b/proto/containers/BUILD
index 0471cfa59d0..302a186a491 100644
--- a/proto/containers/BUILD
+++ b/proto/containers/BUILD
@@ -81,6 +81,15 @@ proto_library(
     ],
 )
 
+# TODO(#4392): Remove once the migration is complete.
+proto_library(
+    name = "orchestrator_crypto_proto",
+    srcs = ["orchestrator_crypto.proto"],
+    deps = [
+        "//oak_crypto/proto/v1:crypto_proto",
+    ],
+)
+
 build_test(
     name = "build_test",
     targets = [
diff --git a/proto/containers/orchestrator_crypto.proto b/proto/containers/orchestrator_crypto.proto
new file mode 100644
index 00000000000..f503f70951c
--- /dev/null
+++ b/proto/containers/orchestrator_crypto.proto
@@ -0,0 +1,64 @@
+//
+// Copyright 2023 The Project Oak 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.
+//
+
+syntax = "proto3";
+
+// TODO(#4392): Remove this file once the migration is complete.
+// This file is deprecated, the relevant functionality is available in `proto/containers/application_interfaces.proto`.
+// DO NOT MODIFY THIS FILE, DO NOT ADD NEW DEPENDENCIES ON IT.
+
+package oak.containers.v1;
+
+import "oak_crypto/proto/v1/crypto.proto";
+
+// Choice between a key generated by the enclave instance and the key distributed to the enclave
+// group with Key Provisioning.
+enum KeyOrigin {
+  KEY_ORIGIN_UNSPECIFIED = 0;
+  INSTANCE = 1;
+  GROUP = 2;
+}
+
+message DeriveSessionKeysRequest {
+  KeyOrigin key_origin = 1;
+  // Ephemeral Diffie-Hellman client public key that is needed to derive session keys.
+  bytes serialized_encapsulated_public_key = 2;
+}
+
+message DeriveSessionKeysResponse {
+  // Session keys for decrypting client requests and encrypting enclave responses.
+  oak.crypto.v1.SessionKeys session_keys = 1;
+}
+
+message SignRequest {
+  KeyOrigin key_origin = 1;
+  bytes message = 2;
+}
+
+message SignResponse {
+  oak.crypto.v1.Signature signature = 1;
+}
+
+// RPC service that is exposed to an enclave application and allows it to:
+// - Encrypt/decrypt messages
+// - Sign arbitrary data
+// TODO(#4504): Implement data signing.
+service OrchestratorCrypto {
+  // Derives session keys for decrypting client requests and encrypting enclave responses.
+  rpc DeriveSessionKeys(DeriveSessionKeysRequest) returns (DeriveSessionKeysResponse) {}
+  // Signs the provided message using the hardware rooted signing key.
+  rpc Sign(SignRequest) returns (SignResponse) {}
+}

From 0460e40dfc25bdf7650f5024c38d49b6b57f4109 Mon Sep 17 00:00:00 2001
From: Juliette Pretot <julsh@google.com>
Date: Wed, 17 Jan 2024 20:25:49 +0000
Subject: [PATCH 4/7] apply formatting

---
 oak_containers/proto/interfaces.proto         | 5 +++--
 proto/containers/BUILD                        | 9 ++++-----
 proto/containers/application_interfaces.proto | 1 -
 proto/containers/launcher.proto               | 1 -
 proto/containers/orchestrator_crypto.proto    | 5 +++--
 5 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/oak_containers/proto/interfaces.proto b/oak_containers/proto/interfaces.proto
index d886a43dac7..704845919ba 100644
--- a/oak_containers/proto/interfaces.proto
+++ b/oak_containers/proto/interfaces.proto
@@ -17,8 +17,9 @@
 syntax = "proto3";
 
 // TODO(#4392): Remove this file once the migration is complete.
-// This file is deprecated. The relevant functionality is available in `proto/containers/application_interfaces.proto` & `proto/containers/launcher.proto`.
-// DO NOT MODIFY THIS FILE, DO NOT ADD NEW DEPENDENCIES ON IT.
+// This file is deprecated. The relevant functionality is available in
+// `proto/containers/application_interfaces.proto` & `proto/containers/launcher.proto`. DO NOT
+// MODIFY THIS FILE, DO NOT ADD NEW DEPENDENCIES ON IT.
 
 package oak.containers;
 
diff --git a/proto/containers/BUILD b/proto/containers/BUILD
index 302a186a491..eb1b72b474c 100644
--- a/proto/containers/BUILD
+++ b/proto/containers/BUILD
@@ -15,10 +15,10 @@
 #
 
 load("@bazel_skylib//rules:build_test.bzl", "build_test")
-load("@rules_proto//proto:defs.bzl", "proto_library")
-load("@rules_cc//cc:defs.bzl", "cc_proto_library")
 load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
 load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
+load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("@rules_proto//proto:defs.bzl", "proto_library")
 
 package(
     default_visibility = ["//visibility:public"],
@@ -34,10 +34,10 @@ proto_library(
     name = "application_interfaces_proto",
     srcs = ["application_interfaces.proto"],
     deps = [
+        ":common_proto",
         "//oak_crypto/proto/v1:crypto_proto",
         "//oak_remote_attestation/proto/v1:messages_proto",
         "@com_google_protobuf//:empty_proto",
-        ":common_proto"
     ],
 )
 
@@ -53,7 +53,6 @@ cc_grpc_library(
     deps = [":application_interfaces_proto"],
 )
 
-
 py_proto_library(
     name = "application_interfaces_py_proto",
     deps = [":application_interfaces_proto"],
@@ -95,6 +94,6 @@ build_test(
     targets = [
         ":hostlib_key_provisioning_proto",
         ":application_interfaces_proto",
-        ":launcher_proto"
+        ":launcher_proto",
     ],
 )
diff --git a/proto/containers/application_interfaces.proto b/proto/containers/application_interfaces.proto
index aee61cf3553..327fcece1f2 100644
--- a/proto/containers/application_interfaces.proto
+++ b/proto/containers/application_interfaces.proto
@@ -35,7 +35,6 @@ service Orchestrator {
   rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
 }
 
-
 // Choice between a key generated by the enclave instance and the key distributed to the enclave
 // group with Key Provisioning.
 enum KeyOrigin {
diff --git a/proto/containers/launcher.proto b/proto/containers/launcher.proto
index 2c84830d37f..c64192f8efb 100644
--- a/proto/containers/launcher.proto
+++ b/proto/containers/launcher.proto
@@ -23,7 +23,6 @@ import "proto/attestation/evidence.proto";
 import "proto/session/messages.proto";
 import "proto/containers/common.proto";
 
-
 // As images can be large (hundreds of megabytes), the launcher chunks up the response into smaller
 // pieces to respect proto/gRPC limits. The image needs to be reassembled in the stage1 or the
 // orchestrator.
diff --git a/proto/containers/orchestrator_crypto.proto b/proto/containers/orchestrator_crypto.proto
index f503f70951c..1386b4296b3 100644
--- a/proto/containers/orchestrator_crypto.proto
+++ b/proto/containers/orchestrator_crypto.proto
@@ -17,8 +17,9 @@
 syntax = "proto3";
 
 // TODO(#4392): Remove this file once the migration is complete.
-// This file is deprecated, the relevant functionality is available in `proto/containers/application_interfaces.proto`.
-// DO NOT MODIFY THIS FILE, DO NOT ADD NEW DEPENDENCIES ON IT.
+// This file is deprecated, the relevant functionality is available in
+// `proto/containers/application_interfaces.proto`. DO NOT MODIFY THIS FILE, DO NOT ADD NEW
+// DEPENDENCIES ON IT.
 
 package oak.containers.v1;
 

From e6c19f71cbaec4e57069e486cdd4c05c51ff8b8c Mon Sep 17 00:00:00 2001
From: Juliette Pretot <julsh@google.com>
Date: Thu, 18 Jan 2024 17:42:39 +0000
Subject: [PATCH 5/7] remove outdated todo

---
 proto/containers/application_interfaces.proto | 1 -
 1 file changed, 1 deletion(-)

diff --git a/proto/containers/application_interfaces.proto b/proto/containers/application_interfaces.proto
index 327fcece1f2..fdfae9e396b 100644
--- a/proto/containers/application_interfaces.proto
+++ b/proto/containers/application_interfaces.proto
@@ -66,7 +66,6 @@ message SignResponse {
 // RPC service that is exposed to an enclave application and allows it to:
 // - Encrypt/decrypt messages
 // - Sign arbitrary data
-// TODO(#4504): Implement data signing.
 service OrchestratorCrypto {
   // Derives session keys for decrypting client requests and encrypting enclave responses.
   rpc DeriveSessionKeys(DeriveSessionKeysRequest) returns (DeriveSessionKeysResponse) {}

From 3ae4f3615b5fdfb0138a81fdf601f41c89a1afbc Mon Sep 17 00:00:00 2001
From: Juliette Pretot <julsh@google.com>
Date: Fri, 26 Jan 2024 17:17:27 +0000
Subject: [PATCH 6/7] build mocks

---
 proto/containers/BUILD | 1 +
 1 file changed, 1 insertion(+)

diff --git a/proto/containers/BUILD b/proto/containers/BUILD
index eb1b72b474c..5965b89709b 100644
--- a/proto/containers/BUILD
+++ b/proto/containers/BUILD
@@ -50,6 +50,7 @@ cc_grpc_library(
     name = "application_interfaces_cc_grpc",
     srcs = [":application_interfaces_proto"],
     grpc_only = True,
+    generate_mocks = True,
     deps = [":application_interfaces_proto"],
 )
 

From 16f0b7a7290540b9a9e037952f7a3e9c657b6f20 Mon Sep 17 00:00:00 2001
From: Juliette Pretot <julsh@google.com>
Date: Fri, 26 Jan 2024 17:26:51 +0000
Subject: [PATCH 7/7] publicly import services and messages, instead of
 duplicating them

---
 oak_containers/proto/interfaces.proto | 68 ++-------------------------
 1 file changed, 5 insertions(+), 63 deletions(-)

diff --git a/oak_containers/proto/interfaces.proto b/oak_containers/proto/interfaces.proto
index 704845919ba..4cde02521d0 100644
--- a/oak_containers/proto/interfaces.proto
+++ b/oak_containers/proto/interfaces.proto
@@ -17,69 +17,11 @@
 syntax = "proto3";
 
 // TODO(#4392): Remove this file once the migration is complete.
-// This file is deprecated. The relevant functionality is available in
-// `proto/containers/application_interfaces.proto` & `proto/containers/launcher.proto`. DO NOT
-// MODIFY THIS FILE, DO NOT ADD NEW DEPENDENCIES ON IT.
+// This file is deprecated. The relevant functionality is available in the
+// publicly imported protos instead. Do not add new dependencies on this file.
 
 package oak.containers;
 
-import "google/protobuf/empty.proto";
-import "oak_crypto/proto/v1/crypto.proto";
-import "proto/attestation/endorsement.proto";
-import "proto/attestation/evidence.proto";
-import "proto/session/messages.proto";
-
-// As images can be large (hundreds of megabytes), the launcher chunks up the response into smaller
-// pieces to respect proto/gRPC limits. The image needs to be reassembled in the stage1 or the
-// orchestrator.
-message GetImageResponse {
-  bytes image_chunk = 1;
-}
-
-message GetApplicationConfigResponse {
-  // Arbitrary config that the container can retrieve from the orchestrator.
-  // Included in the attestation measurements conducted by the orchestrator.
-  bytes config = 1;
-}
-
-message SendAttestationEvidenceRequest {
-  oak.session.v1.AttestationEvidence evidence = 1 [deprecated = true];
-  oak.attestation.v1.Evidence dice_evidence = 2;
-}
-
-// Defines the service exposed by the launcher, that can be invoked by the stage1 and the
-// orchestrator.
-service Launcher {
-  // Provides stage1 with the Oak system image (which contains the Linux distribution and the
-  // orchestrator binary).
-  rpc GetOakSystemImage(google.protobuf.Empty) returns (stream GetImageResponse) {}
-
-  // Provides orchestrator with the trusted container image.
-  rpc GetContainerBundle(google.protobuf.Empty) returns (stream GetImageResponse) {}
-
-  // This method is used by the orchestrator to load and measure the trusted
-  // application config. The orchestrator will later, separately expose this
-  // config to the application.
-  rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {}
-
-  // Sends Attestation Evidence containing the Attestation Report with corresponding measurements
-  // and public keys to the Launcher.
-  // This API is called exactly once after the Attestation Evidence is generated. Calling this API
-  // a second time will result in an error.
-  rpc SendAttestationEvidence(SendAttestationEvidenceRequest) returns (google.protobuf.Empty) {}
-
-  // Notifies the launcher that the trusted app is ready to serve requests and listening on the
-  // pre-arranged port (8080).
-  rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
-}
-
-// Defines the service exposed by the orchestrator, that can be invoked by the application.
-service Orchestrator {
-  // Exposes the previously loaded trusted application config to the application,
-  // which may choose to retrieve it.
-  rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {}
-
-  // Notifies the orchestrator that the trusted app is ready to serve requests and listening on the
-  // pre-arranged port (8080).
-  rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {}
-}
+import public "proto/containers/common.proto";
+import public "proto/containers/launcher.proto";
+import public "proto/containers/application_interfaces.proto";