-
Notifications
You must be signed in to change notification settings - Fork 231
add api-key parameter #3690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add api-key parameter #3690
Changes from 7 commits
4e9df48
9bb4cac
197109f
137a7bd
c335a5a
d9d22b0
3af935a
2342e80
f8e18d9
8168727
48e4013
5962b1f
5127127
d8af40b
ae6fe1a
66a9815
9e76259
7a69454
cf5eef9
e3c4e18
cbabe42
6607d66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,13 +5,9 @@ | |||||
| By default, the OpenVINO Model Server containers start with the security context of a local account `ovms` with Linux UID 5000. This ensures the Docker container does not have elevated permissions on the host machine. This is in line with best practices to use minimal permissions when running containerized applications. You can change the security context by adding the `--user` parameter to the Docker run command. This may be needed for loading mounted models with restricted access. | ||||||
| For additional security hardening, you might also consider preventing write operations on the container root filesystem by adding a `--read-only` flag. This prevents undesired modification of the container files. In case the cloud storage used for the model repository (S3, Google Storage, or Azure storage) is restricting the root filesystem, it should be combined with `--tmpfs /tmp` flag. | ||||||
|
|
||||||
| ```bash | ||||||
| mkdir -p models/resnet/1 | ||||||
| wget -P models/resnet/1 https://storage.openvinotoolkit.org/repositories/open_model_zoo/2022.1/models_bin/2/resnet50-binary-0001/FP32-INT1/resnet50-binary-0001.bin | ||||||
| wget -P models/resnet/1 https://storage.openvinotoolkit.org/repositories/open_model_zoo/2022.1/models_bin/2/resnet50-binary-0001/FP32-INT1/resnet50-binary-0001.xml | ||||||
|
|
||||||
| docker run --rm -d --user $(id -u):$(id -g) --read-only --tmpfs /tmp -v ${PWD}/models/:/models -p 9178:9178 openvino/model_server:latest \ | ||||||
| --model_path /models/resnet/ --model_name resnet --port 9178 | ||||||
| ``` | ||||||
| docker run --rm -d --user $(id -u):$(id -g) --read-only --tmpfs /tmp -v ${PWD}/models/:/models -p 9000:9000 openvino/model_server:latest \ | ||||||
| --model_path s3://bucket/model --model_name model --port 9000 | ||||||
|
|
||||||
| ``` | ||||||
| --- | ||||||
|
|
@@ -21,11 +17,16 @@ See also: | |||||
| - [Securing OVMS with NGINX](../extras/nginx-mtls-auth/README.md) | ||||||
| - [Securing models with OVSA](https://docs.openvino.ai/2025/about-openvino/openvino-ecosystem/openvino-project/openvino-security-add-on.html) | ||||||
|
|
||||||
| --- | ||||||
| Generative endpoints starting with `/v3`, might be restricted with authorization and API key. It can be set during the server initialization with a parameter `api_key_file` or environment variable `API_KEY`. | ||||||
| The `api_key_file` should contains a path to the file containing the value of API key. The content of the file first line is used. If parameter api_key_file and variable API_KEY are not set, the server will not require any authorization. The client should send the API key inside the `Authorization` header as `Bearer <api_key>`. | ||||||
|
||||||
| The `api_key_file` should contains a path to the file containing the value of API key. The content of the file first line is used. If parameter api_key_file and variable API_KEY are not set, the server will not require any authorization. The client should send the API key inside the `Authorization` header as `Bearer <api_key>`. | |
| The `api_key_file` should contain a path to the file containing the value of API key. The content of the file first line is used. If parameter api_key_file and variable API_KEY are not set, the server will not require any authorization. The client should send the API key inside the `Authorization` header as `Bearer <api_key>`. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is parameter name correct? grpc_rest_workers
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |||||
| //***************************************************************************** | ||||||
| #include "cli_parser.hpp" | ||||||
|
|
||||||
| #include <filesystem> | ||||||
| #include <iostream> | ||||||
| #include <stdexcept> | ||||||
| #include <string> | ||||||
|
|
@@ -35,6 +36,7 @@ | |||||
| namespace ovms { | ||||||
|
|
||||||
| constexpr const char* CONFIG_MANAGEMENT_HELP_GROUP{"config management"}; | ||||||
| constexpr const char* API_KEY_ENV_VAR{"API_KEY"}; | ||||||
|
|
||||||
| std::string getConfigPath(const std::string& configPath) { | ||||||
| bool isDir = false; | ||||||
|
|
@@ -160,7 +162,11 @@ void CLIParser::parse(int argc, char** argv) { | |||||
| ("allowed_headers", | ||||||
| "Comma separated list of headers that are allowed to access the API. Default: *.", | ||||||
| cxxopts::value<std::string>()->default_value("*"), | ||||||
| "ALLOWED_HEADERS"); | ||||||
| "ALLOWED_HEADERS") | ||||||
| ("api_key_file", | ||||||
| "path to the text file containing API key for authentication for generative endpoints. If not set, authentication is disabled.", | ||||||
| cxxopts::value<std::string>()->default_value(""), | ||||||
| "API_KEY"); | ||||||
|
|
||||||
| options->add_options("multi model") | ||||||
| ("config_path", | ||||||
|
|
@@ -493,6 +499,31 @@ void CLIParser::prepareServer(ServerSettingsImpl& serverSettings) { | |||||
| serverSettings.allowedOrigins = result->operator[]("allowed_origins").as<std::string>(); | ||||||
| serverSettings.allowedMethods = result->operator[]("allowed_methods").as<std::string>(); | ||||||
| serverSettings.allowedHeaders = result->operator[]("allowed_headers").as<std::string>(); | ||||||
| std::filesystem::path api_key_file = result->operator[]("api_key_file").as<std::string>(); | ||||||
|
||||||
| std::filesystem::path api_key_file = result->operator[]("api_key_file").as<std::string>(); | |
| std::filesystem::path apiKeyFile= result->operator[]("api_key_file").as<std::string>(); |
dtrawins marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just cerr here & exit, instead of throw & instant catch?
atobiszei marked this conversation as resolved.
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -51,8 +51,11 @@ class Server { | |||||||||||||||
| virtual ~Server(); | ||||||||||||||||
| Status startModules(ovms::Config& config); | ||||||||||||||||
| void shutdownModules(); | ||||||||||||||||
| std::string getAPIKey() const; | ||||||||||||||||
| std::string setAPIKey(const std::string& newApiKey); | ||||||||||||||||
|
||||||||||||||||
| std::string setAPIKey(const std::string& newApiKey); | |
| std::string setAPIKey(const std::string& newApiKey) { | |
| std::unique_lock<std::shared_mutex> lock(modulesMtx); | |
| std::string oldApiKey = apiKey; | |
| apiKey = newApiKey; | |
| return oldApiKey; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HttpServerModule has access to ovms::config in HTTPServerModule::start(ovms::Config)
Either extend ovms::createAndStartDrogonHttpServer() with additional parameter or wrap
apiKey together with restBindAddress,restPort, workersCount in helper struct nested inside server settings (HTTPServerConfig?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bump
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -133,6 +133,7 @@ const std::unordered_map<StatusCode, std::string> Status::statusMessageMap = { | |||||
| {StatusCode::UNKNOWN_REQUEST_COMPONENTS_TYPE, "Request components type not recognized"}, | ||||||
| {StatusCode::FAILED_TO_PARSE_MULTIPART_CONTENT_TYPE, "Request of multipart type but failed to parse"}, | ||||||
| {StatusCode::FAILED_TO_DEDUCE_MODEL_NAME_FROM_URI, "Failed to deduce model name from all possible ways"}, | ||||||
| {StatusCode::UNAUTHORIZED, "Unauthorized request due to invalid api-key"}, | ||||||
|
||||||
| {StatusCode::UNAUTHORIZED, "Unauthorized request due to invalid api-key"}, | |
| {StatusCode::UNAUTHORIZED, "Unauthorized request due to invalid or missing api-key"}, |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -176,6 +176,7 @@ enum class StatusCode { | |||||
| UNKNOWN_REQUEST_COMPONENTS_TYPE, /*!< Components type not recognized */ | ||||||
| FAILED_TO_PARSE_MULTIPART_CONTENT_TYPE, /*!< Request of multipart type but failed to parse */ | ||||||
| FAILED_TO_DEDUCE_MODEL_NAME_FROM_URI, /*!< Failed to deduce model name from all possible ways */ | ||||||
| UNAUTHORIZED, /*!< Unauthorized request due to invalid api-key*/ | ||||||
|
||||||
| UNAUTHORIZED, /*!< Unauthorized request due to invalid api-key*/ | |
| UNAUTHORIZED, /*!< Unauthorized request due to invalid or missing api-key*/ |
Uh oh!
There was an error while loading. Please reload this page.