Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
304561c
[Serving] Implement SageMaker Secure Mode
ethnzhng May 28, 2024
35ee95e
Add comment
ethnzhng Jun 10, 2024
d59872e
Revert some changes
ethnzhng Jun 11, 2024
7f41975
Change SageMaker platform env var prefix
ethnzhng Jun 11, 2024
48cefb6
Create empty securemode plugin
ethnzhng Jun 11, 2024
02e5866
Throw ModelException for security checks
ethnzhng Jun 11, 2024
321cfdc
Temp comment out requirements linking
ethnzhng Jun 11, 2024
5de5809
Update plugin. Move secure mode out of wlm
ethnzhng Jun 11, 2024
5813399
Test plugin
ethnzhng Jun 11, 2024
0ef637a
Fix plugin build & style
ethnzhng Jun 11, 2024
179a1c8
Initial add validate security to plugin
ethnzhng Jun 11, 2024
1ae5230
trim security controls
ethnzhng Jun 12, 2024
490e5e9
Add unit tests for secure mode plugin with mock env vars
ethnzhng Jun 12, 2024
dea2843
re-enable requirements linking
ethnzhng Jun 12, 2024
255b723
Require entryPoint to be set to non-null in secure mode.
ethnzhng Jun 12, 2024
2dedd81
Fix style
ethnzhng Jun 12, 2024
3280869
Fix reconcileSources
ethnzhng Jun 12, 2024
bd93486
FIx unit test
ethnzhng Jun 12, 2024
81fea13
move mockito-core version to libs.versions.toml
ethnzhng Jun 12, 2024
c8720e3
rename plugin and logger
ethnzhng Jun 12, 2024
127a17c
Rename plugin folder and create IllegalConfigurationException wrapper
ethnzhng Jun 12, 2024
55e3cce
Fix mockito libs version
ethnzhng Jun 12, 2024
2c58794
Address comments
ethnzhng Jun 12, 2024
ac65f50
Simplify code and remove unneeded methods
ethnzhng Jun 12, 2024
aaec1ca
Update tests
ethnzhng Jun 12, 2024
23b9555
Format
ethnzhng Jun 12, 2024
a3afe70
Update Readme
ethnzhng Jun 12, 2024
8379f06
Scan for model.py during entrypoint check
ethnzhng Jun 12, 2024
e583021
Bring splitCommaSeparatedString to trim whitespace
ethnzhng Jun 13, 2024
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
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ httpcomponents = "4.5.14"

testng = "7.10.2"
junit = "4.13.2"
mockitocore = "5.12.0"

[libraries]
huggingface-tokenizers = { module = "ai.djl.huggingface:tokenizers" }
Expand All @@ -41,3 +42,4 @@ prometheus-exposition-formats = { module = "io.prometheus:prometheus-metrics-exp

testng = { module = "org.testng:testng", version.ref = "testng" }
junit = { module = "junit:junit", version.ref = "junit" }
mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockitocore" }
3 changes: 3 additions & 0 deletions plugins/secure-mode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# DJL Serving - Secure Mode Plugin

This plugin implements SageMaker Secure Mode for the model server, by performing checks for potentially unsafe files and options. It is configured by the SageMaker platform.
23 changes: 23 additions & 0 deletions plugins/secure-mode/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
plugins {
ai.djl.javaProject
}

dependencies {
implementation(project(":serving"))
implementation(project(":wlm"))

testImplementation(libs.testng) {
exclude(group = "junit", module = "junit")
}
testImplementation(libs.mockito.core)

}

tasks {
register<Copy>("copyJar") {
from(jar) // here it automatically reads jar file produced from jar task
into("../../serving/plugins")
}

jar { finalizedBy("copyJar") }
}
1 change: 1 addition & 0 deletions plugins/secure-mode/gradlew
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
package ai.djl.serving.plugins.securemode;

/** Thrown when Secure Mode encounters a violation during security checks. */
public class IllegalConfigurationException extends RuntimeException {

static final long serialVersionUID = 1L;

/**
* Constructs a {@link IllegalConfigurationException} with the specified detail message.
*
* @param message The detail message (which is saved for later retrieval by the {@link
* #getMessage()} method)
*/
public IllegalConfigurationException(String message) {
super(message);
}

/**
* Constructs a {@link IllegalConfigurationException} with the specified detail message and
* cause.
*
* <p>Note that the detail message associated with {@code cause} is <i>not</i> automatically
* incorporated into this exception's detail message.
*
* @param message The detail message (which is saved for later retrieval by the {@link
* #getMessage()} method)
* @param cause The cause (which is saved for later retrieval by the {@link #getCause()}
* method). (A null value is permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public IllegalConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
package ai.djl.serving.plugins.securemode;

import ai.djl.Device;
import ai.djl.ModelException;
import ai.djl.serving.wlm.ModelInfo;
import ai.djl.serving.wlm.util.ModelServerListenerAdapter;

import java.io.IOException;
import java.net.URISyntaxException;

class SecureModeModelServerListener extends ModelServerListenerAdapter {

@Override
public void onModelLoading(ModelInfo<?, ?> model, Device device) {
super.onModelLoading(model, device);

if (SecureModeUtils.isSecureMode()) {
try {
SecureModeUtils.validateSecurity();
SecureModeUtils.reconcileSources(model.getModelUrl());
} catch (ModelException e) {
throw new IllegalConfigurationException("Secure Mode check failed", e);
} catch (IOException | URISyntaxException e) {
throw new IllegalConfigurationException(
"Error while running Secure Mode checks", e);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
package ai.djl.serving.plugins.securemode;

import ai.djl.serving.plugins.RequestHandler;
import ai.djl.serving.wlm.util.EventManager;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.QueryStringDecoder;

/** A plugin for Secure Mode. */
public class SecureModePlugin implements RequestHandler<Void> {

/** Constructs a new {@code SecureModePlugin} instance. */
public SecureModePlugin() {
if (SecureModeUtils.isSecureMode()) {
EventManager.getInstance().addListener(new SecureModeModelServerListener());
}
}

/** {@inheritDoc} */
@Override
public boolean acceptInboundMessage(Object msg) {
return false;
}

/** {@inheritDoc} */
@Override
public Void handleRequest(
ChannelHandlerContext ctx,
FullHttpRequest req,
QueryStringDecoder decoder,
String[] segments) {
return null;
}
}
Loading