Skip to content

Commit

Permalink
release Protected Download
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 509476510
  • Loading branch information
PCS Team authored and Copybara-Service committed Feb 14, 2023
1 parent 8b76a1d commit 1f7cf2c
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 1 deletion.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -48,6 +48,9 @@ You can learn more about Private Compute Services in this
* Federated compute: Enables privacy-preserving aggregate machine learning and
analytics across many devices, without any raw data leaving the device.
* HTTP download: Enables access to static resources like updated ML models.
* [Protected Download](pd/README.md): enables downloading of resources to the
device with support for a binary transparency log based verification,
ensuring these are the official resources provided by Google.

## Note on dependencies

Expand All @@ -59,3 +62,4 @@ The open sourced dependencies are:

* [Federated compute](https://github.com/google/federated-compute)
* [Private retrieval](https://github.com/google/private-retrieval)
* [Tink](https://github.com/google/tink)
5 changes: 5 additions & 0 deletions src/com/google/android/as/oss/common/ExecutorAnnotations.java
Expand Up @@ -44,5 +44,10 @@ public abstract class ExecutorAnnotations {
@Retention(RetentionPolicy.RUNTIME)
public @interface IoExecutorQualifier {}

/** Annotation to bind {@link Executor} used for protected download. */
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ProtectedDownloadExecutorQualifier {}

private ExecutorAnnotations() {}
}
7 changes: 7 additions & 0 deletions src/com/google/android/as/oss/common/Executors.java
Expand Up @@ -18,6 +18,7 @@

import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.Executor;

/** Declares static Executors used in PCS. */
Expand All @@ -28,5 +29,11 @@ public class Executors {
java.util.concurrent.Executors.newSingleThreadExecutor();
public static final Executor PIR_EXECUTOR = java.util.concurrent.Executors.newCachedThreadPool();

public static final ListeningScheduledExecutorService PROTECTED_DOWNLOAD_EXECUTOR =
MoreExecutors.listeningDecorator(
java.util.concurrent.Executors.newScheduledThreadPool(
/* corePoolSize= */ 1,
new ThreadFactoryBuilder().setNameFormat("pcs-pd-%d").build()));

private Executors() {}
}
9 changes: 9 additions & 0 deletions src/com/google/android/as/oss/common/ExecutorsModule.java
Expand Up @@ -20,6 +20,8 @@
import com.google.android.as.oss.common.ExecutorAnnotations.GeneralExecutorQualifier;
import com.google.android.as.oss.common.ExecutorAnnotations.IoExecutorQualifier;
import com.google.android.as.oss.common.ExecutorAnnotations.PirExecutorQualifier;
import com.google.android.as.oss.common.ExecutorAnnotations.ProtectedDownloadExecutorQualifier;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import dagger.Module;
import dagger.Provides;
Expand Down Expand Up @@ -60,5 +62,12 @@ static Executor ioExecutor() {
return Executors.IO_EXECUTOR;
}

@Provides
@Singleton
@ProtectedDownloadExecutorQualifier
static ListeningExecutorService protectedDownloadExecutor() {
return Executors.PROTECTED_DOWNLOAD_EXECUTOR;
}

private ExecutorsModule() {}
}
Expand Up @@ -31,10 +31,15 @@ message PirConnectionKey {
optional string url_regex = 1;
}

message PdConnectionKey {
optional string client_id = 1;
}

message ConnectionKey {
oneof connection_key {
FlConnectionKey fl_connection_key = 1;
HttpConnectionKey http_connection_key = 2;
PirConnectionKey pir_connection_key = 3;
PdConnectionKey pd_connection_key = 4;
}
}
Expand Up @@ -87,7 +87,9 @@ public enum ConnectionType {
/** A download using HTTPS. */
HTTP,
/** A download using Private Information Retrieval. */
PIR
PIR,
/** A protected download using a GRPC-based protocol. */
PD
}

/**
Expand Down
Expand Up @@ -50,6 +50,19 @@ public static ConnectionDetails createPirConnectionDetails(String urlRegex, Stri
.build();
}

public static ConnectionDetails createPdConnectionDetails(String clientId, String packageName) {
checkArgument(!Strings.isNullOrEmpty(clientId));
return getDefaultConnectionDetailsBuilder(ConnectionType.PD, packageName)
.setConnectionKey(
ConnectionKey.newBuilder()
.setPdConnectionKey(
com.google.android.as.oss.networkusage.api.proto.PdConnectionKey.newBuilder()
.setClientId(clientId)
.build())
.build())
.build();
}

public static ConnectionDetails createFcCheckInConnectionDetails() {
return getDefaultConnectionDetailsBuilder(ConnectionType.FC_CHECK_IN).build();
}
Expand Down Expand Up @@ -113,6 +126,15 @@ public static NetworkUsageEntity createFcTrainingStartQueryNetworkUsageEntity(
.build();
}

public static NetworkUsageEntity createPdNetworkUsageEntry(
ConnectionDetails connectionDetails, Status status, long size, String clientId) {
checkArgument(connectionDetails.type() == ConnectionType.PD);
checkArgument(connectionDetails.connectionKey().hasPdConnectionKey());
checkArgument(
clientId.equals(connectionDetails.connectionKey().getPdConnectionKey().getClientId()));
return getNetworkUsageEntityBuilder(connectionDetails, status, size).build();
}

private static NetworkUsageEntity getNetworkUsageEntityForUrl(
ConnectionDetails connectionDetails, Status status, long size, String url) {
checkArgument(!Strings.isNullOrEmpty(url));
Expand Down
Expand Up @@ -40,6 +40,9 @@ public interface NetworkUsageLogContentMap {
*/
Optional<ConnectionDetails> getFcStartQueryConnectionDetails(String featureName);

/** Returns the ConnectionDetails object for PD connections with the given client Id. */
Optional<ConnectionDetails> getPdConnectionDetails(String clientId);

/** Returns the feature name corresponding to the given ConnectionDetails. */
Optional<String> getFeatureName(ConnectionDetails connectionDetails);

Expand Down
Expand Up @@ -39,6 +39,11 @@ public Optional<ConnectionDetails> getPirConnectionDetails(String url) {
return Optional.empty();
}

@Override
public Optional<ConnectionDetails> getPdConnectionDetails(String clientId) {
return Optional.empty();
}

@Override
public Optional<ConnectionDetails> getFcStartQueryConnectionDetails(String featureName) {
return Optional.empty();
Expand Down
30 changes: 30 additions & 0 deletions src/com/google/android/as/oss/pd/README.md
@@ -0,0 +1,30 @@
<!--
Copyright 2021 Google LLC
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.
-->

# Protected Download Protocol / API

Protected Download enables downloading of resources to the device with support
for a binary transparency log based verification, ensuring these are the
official resources provided by Google.

This API is used to deliver sensitive models/heuristics to Private Compute Core
apps. The mechanism of download is open-sourced to show that through the
connection to the server personal user data is not sent to Google, but rather
receiving the model or heuristics in an encrypted and verified manner.

As a first use case, this API is used by Google Play Protect Service. As Google
Play Protect Service keeps users safe from malware, the models and heuristics
themselves need to be protected from malware authors.

0 comments on commit 1f7cf2c

Please sign in to comment.