arrow-left

All pages
gitbookPowered by GitBook
1 of 14

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Deployment Models

Deployment models for Seldon Enterprise Platform

When it comes to deploying Seldon Enterprise Platform for a production workload, there are different deployment models that can apply depending on your use case. For example, you can consider the following questions:

  • Do you want to support multiple environments (e.g. production, staging, etc.)? Will these be split across multiple clusters? Or across different namespaces?

  • Are you planning on supporting multiple tenants in your infrastructure? How will you manage permissions for each one of them?

This section will showcase some of the most common deployment models to set up Seldon Enterprise Platform in your cluster.

hashtag
Multiple environments

When you are managing machine learning models, a common use case is to test them first on some kind of test environment, isolated from production workloads. These test environments are usually known as staging, qa, pre-prod, etc.

In some cases, these environments will form a deployment (or continuous delivery) pipeline, where each environment is considered more stable than the previous one:

Dev >... > Staging > Production

Seldon Enterprise Platform allows you to have multiple environments by separating them as namespaces or clusters.

circle-info

Regardless of the approach you choose, this doesn't restrict your options when it comes to syncing your models with a GitOps repository. In fact, you can still have:

  • Single GitOps repository, with one folder per environment.

  • Multiple GitOps repositories, with one repository per environment.

hashtag
Namespace environments

The official Kubernetes docs . Therefore, it makes sense to treat each separate environment as a separate namespace. Following the example above, that would mean creating a dev, staging and production namespaces.

By default, Seldon Enterprise Platform will treat each namespace as a separate environment. Therefore, this is the suggested approach.

Out of the box, this gives you easy control over:

  • Where is each model deployed (on which environments).

  • Who is .

  • Visibility over all your models across every environment from a single instance of Seldon Enterprise Platform.

hashtag
Cluster environments

When you are dealing with multiple environments, it makes sense to keep them completely isolated of each other. That way, any cluster-wide effects will only affect one of them.

Using separate Kubernetes clusters for each of your environments allows you to achieve a higher-level of separation than namespaces. However, this separation also comes with a few caveats:

  • All your infrastructure resources will need to be duplicated and managed across every environment (e.g. auth, ingress, logging, metrics, ...).

  • Operations spanning multiple environments become more complicated (e.g. promotion of models between different environments).

This approach is usually recommended to test new versions of cluster-wide components at the infrastructure level. For example, a new version of Seldon Enterprise Platform or a new ingress system. However, due to the caveats listed above, we don't suggest this approach to segregate different versions of your models.

Having said so, you can still leverage the GitOps paradigm to communicate between different clusters.

define namespaces as virtual clustersarrow-up-right
authorised to view or create models

App Analytics

Seldon Enterprise Platform has built-in app analytics, which help to improve the product. These analytics focus on tracking certain events that get triggered from the UI, for example user login.

circle-info

All events share a distinct_id attribute. This attribute is linked to the IP address, so that each IP address is identified as a unique user.

hashtag
Disable app analytics

You can disable the app analytics through the enableAppAnalytics variable of the Seldon Enterprise Platform Helm chart. To disable it just add the following to your Helm variables:

hashtag
Events tracked

Name
Trigger
Attributes

hashtag
User login attributes

Property
Example Value
Notes

Operations

Operating Seldon Enterprise Platform in your cluster

These pages go into detail on best practices for operators or admins managing a Seldon Enterprise Platform cluster.

  • App Analytics

  • Authorization

Deployment Models
GitOps Sync
Health Check
Kubernetes Resources
LDAP Integrations
Model Metadata
Namespaces
Secrets Management
Single sign-on
Storage Initializers
Usage Monitoring

GitStatus

dirty

ReleaseType

Early-Access

distinct_id

ABABABABABABBABAB

Linked to IP address

user_login

Show homepage after logging in

BuildTime

Wed Apr 22 15:59:09 UTC 2020

BuildVersion

0.6.0

GitBranch

master

GitCommit

5ad34e2b556732213873ee6875f2f99d20a471ee

# boolean to enable app-analytics (defaults to "true")
enableAppAnalytics: false

GitOps Sync

Deployment source control and syncing with Gitops

Seldon Enterprise Platform can recognise that certain namespaces are to be maintained using GitOps. It will look for the label seldon.gitops: enabled.

If the seldon.gitops label is not present or is disabled then new deployments and modifications in the namespace will be pushed directly to the Kubernetes cluster.

If the seldon.gitops label is present then Enterprise Platform will look for an annotation named git-repo with a git URI. It uses a service account token for accessing the repo which is stored in a Secret installed with Seldon Enterprise Platform using the Helm chart (along with username and email). Enterprise Platform will add metadata to any commits it makes, including recording which dex user took the action.

circle-info

Note: Always manage resources in GitOps namespaces via Enterprise Platform--the UI or API--or through the corresponding git repository.

For GitOps namespaces, Seldon Enterprise Platform is only aware of resources defined in the corresponding git repository, but not any created manually in the namespace. As a result, any resources created in a GitOps namespace with kubectl, for example, will be ignored by Enterprise Platform.

Seldon Enterprise Platform can display an Audit Log for each deployment where it reads back git commits and makes the changes and metadata visible:

If the user is permitted then the state can also be restored to a previous commit.

See the for more on how GitOps works.

Kubernetes Resources

Underlying kubernetes resources and debugging

Seldon Enterprise Platform allows a view of the underlying kubernetes resources created by the deployed models. This view displays the pods, deployments and services created for each component of the Seldon Deployment/Inference Service custom CRDs.

k8s_resources

Also for the pods created for each model component, you can dive into the live container logs and debug relevant issues if any.

k8s_pod_logs

Usage Monitoring

Summary metrics are available showing usage over time. These can be accessed from 'Usage' on the top-right menu.

These metrics differ from those shown for individual models on their pages. The summary metrics show multiple models for a namespace or cluster.

By default if the cluster-level is chosen then all models are counted for all namespaces. If you wish to restrict to namespaces visible to the user, set the FILTER_USAGE_MON_NAMESPACES environment variable to true.

Resources are shown broken down by model. The type of resource of interest can be chosen. The containers resource is shown with a comparison against what your license allows for.

Models are stacked on top of each other in the breakdown when there are multiple

relevant Architecture section
Deployment audit logs
usage_monitoring
usage_monitoring

Secrets Management

Seldon Enterprise Platform can create and manage secrets for models or artifacts stored in private buckets, or custom container images stored in a private registry.

If OPA is enabled, you will need write permission to the relevant namespace in order to create or delete secrets in it.

hashtag
Management Methods

Seldon Enterprise Platform supports the management of secrets through both its UI and its API.

You can manage secrets by navigating to the user icon in the top-right of the Seldon Enterprise Platform UI and clicking on Secrets.

You will be greeted by a page similar to the following.

You will be greeted by a page similar to the following.

You can manage secrets via the API by using the provided endpoints under the SecretsService section in the API docs. Those can be accessed either:

  • by navigating to the user icon in the top-right of the Seldon Enterprise Platform UI and clicking on the API docs or

hashtag
Bucket Secrets

Bucket stores, also called blob or object stores, provide storage for arbitrary data files. These might be binary files for serialized models, JSON or other textual formats for model settings, or even inference requests for batch jobs or reference data. Examples of bucket stores include Amazon S3, Azure Blob Storage, and Google Cloud Storage (GCS).

Storage buckets can be publicly accessible, such as Seldon's bucket, or they can be private and protected with some form of secret or access credentials.

Bucket secrets are used in Seldon for accessing various types of data, such as model artifacts and inference data from private bucket stores. It is a that actually uses the secret to perform the download. Secrets need to be provided in a format that the storage initializer understands. The following sections discuss these uses of bucket secrets in more detail.

hashtag
Seldon Core 1

The default storage initializer for Core 1 is , although custom initializers can be used instead.

You can easily configure Rclone-compatible bucket secrets for both S3 and GCS from the UI, or you can also create generic Rclone bucket secrets, which unlocks a wide variety of providers, such as Microsoft Azure Blob Storage, Dropbox, and many more.

Seldon Core 1 uses environment variables to pass configuration to the storage initializer for a model. As such, the keys in a Core 1 bucket secret must be valid environment variables for the initializer.

When creating a bucket secret, you will need to specify a Remote name which will be used to create a secret called <remote>-bucket-envvars. This remote name is your choice and determines how you will refer to your bucket provider in storage URIs, i.e. <remote>://<path to bucket object>.

A GCS bucket secret only requires a Remote name and Account credentials.

Please see the for how to obtain these credentials for your bucket.

For example, to create a GCS bucket secret with a remote called test using a Service Account's private key, in JSON, you need to fill the form in such a way.

This, in turn, will create a bucket secret called test-bucket-envvars. The secret will be made available for selection in Core 1-related wizards and the remote name can be used for specifying private resources, i.e. test://<path to bucket objects>

hashtag
Seldon Core 2

Like Seldon Core 1, both Rclone and custom storage initializers can be used.

When creating a bucket secret, you will need to specify a Remote name which will be used to create a secret called <remote>-bucket-params. This remote name is your choice and determines how you will refer to your bucket provider in storage URIs, i.e. <remote>://<path to bucket object>.

A GCS bucket secret only requires a Remote name and Account credentials.

Please see the for how to obtain these credentials for your bucket.

For example, to create a GCS bucket secret with a remote called test using a Service Account's private key, in JSON, you need to fill the form in such a way.

This, in turn, will create a bucket secret called test-bucket-params. The secret will be made available for selection in Core 2-related wizards and the remote name can be used for specifying private resources, i.e. test://<path to bucket objects>

hashtag
Inference Data

Inference data can be retrieved from and written to storage buckets via batch jobs and reference data uploads.

Batch jobs and reference data jobs in Seldon Enterprise Platform use the same approach as for bucket secrets. Namely, they use environment variables to pass configuration from bucket secrets to a storage initializer. The format is exactly the same as for Core 1 and the same secrets can be used.

The default storage initializer for batch and reference data jobs is Rclone.

hashtag
Registry Secrets

Private container registries can be used when deploying a custom runtime model.

When creating a registry secret, you need to specify the Secret name, which is your choice, and the Account credentials.

The format of container registry credentials can be seen by running the following example. For further information on creating and interacting with registry secrets, please refer to the .

circle-info

The above example displays your personal credentials, which should not be used in a production system.

hashtag
Using Secrets

Once the secrets have been created, you can use them in the Seldon Enterprise Platform UI, e.g. in the Deployment Wizard, and through the API.

For bucket secrets, you need to use the Remote name you chose as the URI prefix. For example, if you named your remote minio then your URI should start with minio://.

For Core 1, the Remote name of your bucket secret should match the prefix of your model URI.

You can use registry secrets for custom model runtimes.

For Core 2, the Remote name of your bucket secret should match the prefix of your model URI.

circle-info

In the Seldon Enterprise Platform UI, you will only be shown secrets with the appropriate format for that context. For example, when creating a Core 1 deployment you will only see env-var bucket secrets.

For backwards compatibility, any bucket secrets that are not labelled with their format are assumed to be in the env-var format.

LDAP Integration

hashtag
Integration Options

Seldon Enterprise Platform integrates with Single Sign-On (SSO) providers for authentication.

The SSO system may also host the identities, or it may integrate to an identity provider (IdP). The IdP is often a source of truth for users across the organisation.

User details can be used for . Filtering is either by user or by group.

In order for group-based filtering to be used, groups need to be available. These come from an IdP but not all IdPs support groups or support groups in integration to SSO.

Health Check

Seldon Enterprise Platform has a built-in health check that aims to monitor the availability of its surrounding ecosystem as well as troubleshoot problems when they arise. This can be done as an intermediary step before checking the logs or contacting us.

hashtag
Where to find the Health Check Monitor

You can find the health check by clicking on the user icon on the top right of the screen.

Then you can select Health Check

by navigating to the corresponding docs page.

In addition to this, the endpoints are also made available through the Seldon Enterprise Platform Python SDKarrow-up-right.

API docs menu
.

Along with a Remote name, an S3 bucket secret requires an Access key ID and a Secret access key.

Please see the AWS documentationarrow-up-right for obtaining these.

S3 secret form

You need to select Core 1 as Seldon core and the Generic Rclone as bucket type.

You can then choose a Remote name and Remote type, and provide configuration parameters for that type as key-value pairs.

Each configuration key will become an environment variable.

These keys must be of the form:

The values <remote name> and <configuration parameter> must be given in uppercase.

Further details on this format can be found in the .

You can find the appropriate Rclone configuration parameters by and checking the available options.

For example, S3 has and .

Note that you should use the config variant of each option as the <config parameter>.

An example for a is shown below for a remote called dropbox:

.

Along with a Remote name, an S3 bucket secret requires an Access key ID and a Secret access key.

Please see the AWS documentationarrow-up-right for obtaining these.

S3 secret form

You need to select Core 2 as Seldon core and the Generic Rclone as bucket type.

After choosing a Remote name, you need to specify the Remote type. This input value is Rclone specific i.e. you need to find out that store's remote type, according to Rclone. For example, the remote type for GCS is google cloud storage, whereas for S3 is s3. Those can be found herearrow-up-right and herearrow-up-right respectively for GCS and S3.

Finally, you need to provide configuration parameters for that type as key-value pairs. You can find the appropriate Rclone configuration parameters by and checking the available options. Note that you should use the config variant of each Rclone parameter.

For batch jobs, whether in Core 1 or Core 2, the Remote name of your bucket secret should match the input and output data locations.

For reference data jobs, whether in Core 1 or Core 2, the Remote name of your bucket secret should match the storage location of your reference data.

Using bucket secrets in the reference data wizard
seldon-modelsarrow-up-right
storage initializer
Rclonearrow-up-right
Google Cloud Auth documentationarrow-up-right
Google Cloud Auth documentationarrow-up-right
Seldon Core 1
Kubernetes documentationarrow-up-right
Secrets menu
Secrets Management page
Secrets management page
GCS secret form
GCS secret form
Create registry secret form
Using Core 1 bucket secrets in the deployment wizard
Using Core 1 registry secrets in the deployment wizard
Using Core 2 secrets in the deployment wizard

Here is a list from the Dex documentation (see their docsarrow-up-right for latest):

Groups

If groups are to be used, we suggest integrating either keycloak or dex to LDAP. See, for example:

  • Keycloak LDAP integration examplearrow-up-right

  • Dex LDAP integration examplearrow-up-right

Or search the official documentation of those products for the latest details.

hashtag
Debugging Keycloak/Groups

Keycloak is the most common choice at present for Identity Provider to integration to LDAP.

If configured correctly you should be able to filter namespaces by group permissions

If you are not sure if groups are coming through, go to the About page in Enterprise Platform and see if a group is shown for your user. Here the group is Data Scientist:

UserAbout

Then open another window and login to keycloak as an admin user. Go to 'Sessions':

Sessions

Click into the Session and click 'Show Sessions':

ShowSessions

Click into that and then go to Groups:

KeycloakGroups

This will tell you whether the Groups are coming through at a Keycloak level.

You can also get the full token from Seldon Enterprise Platform. To do this inspect the browser network tab with preserve logs turned out. Then logout your session. You should see a logout containing the token:

TokenDetails

If you put the content of id_token_hint in jwt.ioarrow-up-right then you can see its contents, including groups.

JWT

If Keycloak has the groups but the token does not, then it is likely the 'groups' scope is missing in the OIDC_SCOPES environment variable in the Seldon Enterprise Platform Helm configuration.

Note that there needs to be a client scope in the keycloak admin console for groups and this needs to be mapped to groups using the group membership mapper type. The scope and token claim name should both be 'groups'. Disable 'full group path'.

The groups scope has to be added as a client scope under the keycloak client config for the client used by Seldon Enterprise Platform.

filtering/restricting visibility of namespaces
.
healthcheck_menu.png

Afterwards, you should see a page like this:

healthcheck.png

hashtag
Health Check Components Explained

circle-info

Note: The health check is still experimental; if you have any issues, please contact us.

Dependency
What does the check do?

Alertmanager

- pings Alertmanager's internal health endpoint

Elasticsearch

- pings Elasticsearch's internal health endpoint

Keycloak

- checks if OIDC provider is available - if the auth url is correctly configured - also adds (as an info) if a user provider is available

Knative

- checks if Knative Eventing CRDs - and Knative Serving CRDs are installed - and if their pods are running

Postgres

- checks first if Postgres is enabled - if it is enabled, the test will try to run a simple query

Prometheus

- pings Prometheus' internal health endpoint

user-header

Single Sign-On

Single sign-on (SSO) is a property of identity and access management (IAM) that enables users to securely authenticate with multiple applications by logging in only once (with just one set of credentials). For SSO, Seldon Enterprise Platform relies on the OIDC protocol that handles authentication through JSON Web Tokens and a central identity provider to verify user identity.

A typical enterprise SSO flow for web based applications is as follows

As shown in the diagram, Seldon Enterprise Platform sso integration works if any enterprise application on domain1.com and a Seldon Enterprise Platform installation on domain2.com is connected to a common auth Server on domain3.com.

Currently, Seldon Enterprise Platform SSO can be configured in

RCLONE_CONFIG_<remote name>_<config parameter>
docker login
cat ~/.docker/config.json

Seldon Core v1

- checks if Seldon Core v1 CRDs are installed - and if the seldon-controller-manager (in Seldon Core v1 namespace) deployment in Kubernetes is ready

Seldon Core v2

- checks if Seldon Core v2 CRDs are installed - and if the seldon-controller-manager (in Seldon Core v2 namespace) deployment in Kubernetes is ready

.
SSO
Rclone documentationarrow-up-right
selecting your storage providerarrow-up-right
standard optionsarrow-up-right
advanced optionsarrow-up-right
Dropbox initializerarrow-up-right
selecting your storage providerarrow-up-right
Rclone secret form
Rclone secret form
Using bucket secrets in the reference data wizard
RCLONE_CONFIG_DROPBOX_CLIENT_ID: <client_id_value>
RCLONE_CONFIG_DROPBOX_CLIENT_SECRET: <client_secret_value>
two ways

Namespaces

Managing Kubernetes namespaces for Seldon Enterprise Platform

Namespaces are where your models are deployed. You can set up GitOps and access controls on a per-namespace basis.

For an introduction to namespaces in Kubernetes, please refer to the official documentationarrow-up-right. The rest of this guide discusses namespaces in the context of Seldon Enterprise Platform.

hashtag
Namespace Detection

Seldon Enterprise Platform requires namespaces to be labelled for use with ML deployments. Otherwise, it will not detect them and so cannot manage resources within them.

You can create a new namespace and make it visible to Enterprise Platform using the following commands:

This is the minimum needed to use a namespace.

hashtag
GitOps

Seldon Enterprise Platform supports GitOps with ArgoCD to manage deployments to a namespace through git.

A namespace can be set up for GitOps with Seldon Enterprise Platform by providing suitable metadata. See for a detailed guide on how to achieve this.

hashtag
Authorization Policies

Seldon Enterprise Platform supports both user-based and group-based authorization policies to control visibility and permissions for namespaces. See the and guides for more details.

Namespaces that the user has access to appear in a drop-down namespace selector in the top-right:

From there the user can search for or choose to drill into deployments:

hashtag
Multi-Tenancy

In a multi-tenant setup, Enterprise Platform is not automatically provided with permissions to manage multiple namespaces. Instead, each namespace needs further permissions to be defined. Details on this can be found in the .

hashtag
Special Namespaces

The seldon-logs namespace is used for infrastructure for inference request logging. It is a special namespace and its setup is covered in the . This namespace should not be used for ML deployments.

the GitOps section
installation
operations
multi-tenant section
request logging section
namespaceselector
DeploymentsFilter
NAMESPACE=<name>
kubectl create namespace $NAMESPACE || echo "namespace $NAMESPACE already exists"
kubectl label namespace $NAMESPACE seldon.restricted=false --overwrite=true

Model Metadata

Seldon Enterprise Platform supports the storage and management of model metadata. This includes project name, artifact URI, ML runtime, and prediction schema, amongst other things.

Model metadata is dependent on Postgres. For more information on configuring Postgres with Seldon Enterprise Platform, see the installation instructions.

You can create and manage model metadata through the Enterprise Platform UI and API. Enterprise Platform will also watch for deployments in the Kubernetes cluster and sync this information into the metadata store. In this case, the Platform will only populate basic information, but this can then be enriched via the UI and API as with any other model metadata.

hashtag
Queries

Seldon Enterprise Platform provides an advanced query language that allows you to make sophisticated search queries over your model metadata.

Simple fields can be compared using SQL-like comparison and partial match operators. Nested fields can be compared by first using index notation to extract simple fields. More complex expressions can be formed with the AND and OR operators and parentheses. Note that the AND and OR operators are treated as having equal precedence.

Operator
Meaning

Field names and operators are not case-sensitive. Field values are case-sensitive, however, and should not be wrapped in quotes. The list of valid fields to query is:

Field name
Type
Description

hashtag
Examples

hashtag
API

Using the model metadata API, you can specify a string query the same way you would in the UI, e.g.

%

Like -- partial match

AND

Conjunction

OR

Disjunction

(...)

Subexpression for ...

artifact_type

Simple

One of ALIBI_DETECT, ALIBI_EXPLAIN, CUSTOM, HUGGINGFACE, MLFLOW, MLSERVER_PYTHON, ONNX, PYTORCH, SKLEARN, TENSORFLOW, TENSORRT, TRITON_PYTHON

task_type

Simple

String, e.g. classification or object-detection

tags

Nested

Map of string to string

metrics

Nested

Map of string to number

=

Equal

!=

Not equal

>

Greater than

<

Less than

>=

Greater than or equal to

<=

Less than or equal to

URI

Simple

String

name

Simple

String

version

Simple

String, e.g. 1.0, v2, dev

project

Simple

String

Authorization

Concepts and configuration for authorization in Seldon Enterprise Platform

hashtag
User Identity

Once a user has been authenticated, they have an identity in the form of an OIDC ID token. The token defines a user ID and groups to which the user belongs. This information can be used to authorize their actions.

The user ID is determined by a claim in the OIDC token. This defaults to preferred_username, but can be configured through the environment variable USERID_CLAIM_KEY in install-values.yaml. This can be used for both human users and service accounts. If it is not possible to share claim keys for both, it is possible to use the environment variable SA_ID_CLAIM_KEY for service accounts.

circle-info

Note: the USERID_CLAIM_KEY is always used if present. SA_ID_CLAIM_KEY is used only if USERID_CLAIM_KEY does not exist in the token.

The groups are determined by a claim in the OIDC token. This defaults to groups, but can be configured through the environment variable GROUPS_CLAIM_KEY in install-values.yaml.

circle-info

Claim is a in the OpenID specification. It means a piece of information about a user, or "entity". You can read more about claims .

hashtag
Permission Evaluation

Every call to the Seldon Enterprise Platform API is protected by authorization checks. This happens regardless of whether you are interacting with it via the UI, via the Python SDK, or directly.

Seldon Enterprise Platform operates on a restrictive model. This means that a user is assumed to have no permissions except those which they have been explicitly granted.

The effective list of permissions that a user has is the union of:

  • Those that are granted to them by their user ID.

  • Those that are granted to all users.

  • Those that are granted to one or more of the groups to which the user belongs.

circle-info

Note: There is no way to define negative permissions, i.e. that a user is denied access to a particular resource.

hashtag
Resource Actions

There are three actions users can be granted for resources:

  • Read for listing available resources and viewing particular ones.

  • Write for creating, deleting, and modifying resources.

  • Grant for granting other users permissions to specific resources.

These actions do not imply one another. For example, having write access does not also grant read access. Each action is handled completely independently in the OPA policies, and each grant must be specified explicitly.

hashtag
Resource Scopes

Resources in Enterprise Platform are grouped into three categories:

  • that belong to a specific Kubernetes namespace. This includes ML deployments and artifact secrets.

  • , including models in the and deployments using these. Projects are a Seldon Enterprise Platform concept, but not a Kubernetes one.

  • , such as authorization policies themselves!

Resources can sometimes be both project-scoped and namespace-scoped. For example, an ML deployment is namespace-scoped because it exists in Kubernetes, and is also project-scoped based on models it uses. When this happens, a user needs access to both the namespace and all projects associated with that deployment to be able to view or interact with it.

hashtag
Projects

A project defines a logical grouping of related resources.

At present, models are the only resources that are explicitly associated with projects. Any model that does not explicitly declare its associated project will be implicitly assigned to the default project.

A project can have multiple models associated with it, but each model is only associated with a single project. Projects-to-models is a one-to-many relationship.

As deployments reference models, they are also protected by project-based policies. Deployments can reference multiple models, so can be associated with multiple different projects. A user must have suitable permissions for all projects associated with a deployment in order to interact with it.

circle-info

Note: The term "model" here refers to inference models, explainers, and detectors.

circle-info

Note: It is advised to have a policy such that the default project is accessible to everyone.

hashtag
Namespaces

A namespace defines a physical grouping of resources.

Any resources related to deployments will exist in a namespace, including deployed models, explainers, detectors, canaries, shadows, and artifact storage secrets.

A namespace can have many resources associated with it, but each resource is only associated with a single namespace. Namespaces-to-resources is a one-to-many relationship.

hashtag
System

System resources are resources that relate to administrative concerns for the Seldon Enterprise Platform platform, instead of ML models and deployments.

Currently the only system-level resources that can be protected by access controls in the Seldon Enterprise Platform API are authorization policies themselves. As a result, the initial policies must be defined by someone with access to the Kubernetes cluster.

hashtag
Associating Scopes With Kubernetes Resources

As namespaces are a native Kubernetes concept, there is a natural association between namespaced resources and their associated namespace.

In contrast, projects are not a native Kubernetes concept and so Seldon Enterprise Platform must record the association between a resource and its project somewhere. It does this via Kubernetes metadata: annotations and labels.

When creating deployments through the Seldon Enterprise Platform UI, you can use the pre-filled value or specify the appropriate project for your model. When creating deployments via the Seldon Enterprise Platform API, whether directly or with the Seldon Enterprise Platform SDK, you must provide the appropriate project metadata in the resource definition. In either case, when no project is explicitly specified then the default project will be used.

For Seldon Core v1, projects are defined via annotations at the predictor level. Each predictor in a deployment's spec.predictors has an annotations field that can contain annotations of the following form:

chevron-rightExample - Seldon Core v1hashtag

Given below is a heavily simplified example of a Seldon Core v1 deployment with a single-model predictor.

The key things to note are the annotations field and the metadata.namespace field. The former corresponds to the mock-example-container model in the graph and associates it with project-a. The latter defines the namespace to be seldon-deployments.

chevron-rightExample - Seldon Core v2hashtag

Given below is an example of a Seldon Core v2 Model.

The key things to note here are the metadata.annotations field, which associates the model with project-a, and the metadata.namespace field, which defines the namespace to be seldon-deployments.

hashtag
Authorization Methods

Currently, there are two ways of defining permissions on the various resources served by Seldon Enterprise Platform:

  • (recommended)

  • (deprecated)

OPA policies are the recommended authorization method for Seldon Enterprise Platform as they can be used to authorize all .

hashtag
OPA Policies

Seldon Enterprise Platform can use Open Policy Agent (OPA) policies to determine if a user has access to a resource. is popular, flexible open-source technology for defining policies. You can enable it by following the .

hashtag
Enable OPA

To enable the use of OPA policies for the namespace and system scopes, set the following Helm variables in install-values.yaml:

As OPA policies cannot be used with , this should be disabled as shown above. However, Seldon Enterprise Platform still requires the seldon.restricted label to be present on namespaces in order to . When using OPA policies, it does not matter whether the value of this label is true or false.

If you also want to enable OPA for projects, set the following configuration in install-values.yaml:

hashtag
Policy Management APIs

Seldon Enterprise Platform has API endpoints for managing OPA policies. These can be found in the .

By default, these are enabled and access can be granted to them on a per-user or group basis. If you want to disable these, set the following Helm value:

hashtag
Policy Schema

OPA policies are defined in a JSON document as resource-action pairs for users or groups. This JSON document exists in a ConfigMap, as discussed in the .

The structure of policies is as follows:

The top-level fields of the document are the grant types: role_grants and user_grants. These are mandatory fields and correspond to groups and user IDs respectively.

Each grant type defines a map from user/group name to a list of permissions. These user or group names are called grant targets.

Each permission is defined as a map, describing an action on a resource scope. For example this permission allows read access to resources in a namespace called seldon:

circle-info

Note: When you do not want to specify either user or role grants, use an empty JSON object as the value.

hashtag
Granting Access For All Users

For user grants, there is a special grant target called the star user and denoted *. This special target can be used to provide policies for all users.

To see how this can be used, please check the .

circle-info

Note: This special star user is not a glob but rather a well-known value that Seldon Enterprise Platform understands.

Seldon Enterprise Platform does not support globbing for user and group names. For example, a grant target like abc* would not be valid. If you need to define permissions for a collection of users, please use role grants.

hashtag
Resource Names

Resources are identified by the as a prefix and a name.

For the system scope, there is only one possible value:

  • system/iam

For the project scope, aside from the default project the names are determined by you:

  • project/default

  • project/foo

  • ...

For the namespace scope, the names should correspond to Kubernetes namespaces for deploying ML models:

  • namespace/seldon

  • namespace/seldon-gitops

  • ...

Seldon Enterprise Platform supports globbing of resource names with an asterisk (*). It is valid to use globbing anywhere within the resource name, but not for the resource scope.

For example, these would all be allowed:

  • "resource": "namespace/*"

  • "resource": "namespace/seldon-*"

  • "resource": "namespace/*-gitops"

On the other hand, these would all be prohibited:

  • "resource": "*"

  • "resource": "*/*"

  • "resource": "*/seldon"

circle-info

Note: For more details on the specifics of each resource type, please see the namespace and project sections.

hashtag
Examples

Giving everyone access to resources in a scope is possible using the special "star" user, *. An example of giving all users access to the default project looks like this:

Giving a group access to resources in a scope is possible using role_grants. An example of giving the data-scientist group access to the prod namespace looks like this:

Giving a user access to resources in a scope is possible using user_grants. An example of giving the alice user access to the system/iam scope looks like this:

An example of a complete policy file is given below.

In this example, users belonging to the data_scientist group will be able to create, modify, and read models from the iris project, as well as see deployments in the seldon namespace. However, they do not have permission to create or modify deployments in that namespace.

Members of the ml_engineer group can create deployments from the iris project in the seldon namespace. They are also allowed to interact with other resources in the seldon namespace, such as storage secrets.

Members of the ops group can view all resources in namespaces with the seldon prefix (including seldon itself), and can see the full Model Catalog.

The * user grant specifies that all users have read and write permissions for the default project and default namespace.

Only the user alice has access to the alice namespace.

hashtag
Policy Operations

hashtag
Interacting With Policies

The policy file can be modified in various ways:

  • Using kubectl

  • Using Seldon's policy_client command-line utility

  • Using the permission management endpoints of the Seldon Enterprise Platform API

You can interact with the ConfigMap directly using kubectl. If your policies are defined in a JSON file called policy.json, you can turn it into a Kubernetes manifest called policy.yaml using the following command:

This resulting policy.yaml file can be tracked under version control if you wish. You can overwrite the existing policies by running the following:

The policy_client command-line utility can be downloaded from the . You will need to download the correct binary for your operating system and architecture, e.g. Linux AMD x64. For full documentation of the tool you can run policy_client --help.

The permission management API is provided via the /iam/policy endpoints discussed in the .

Seldon Enterprise Platform will automatically reload the policies if it detects that they have changed. This is dependent on how the file is mounted and how quickly Kubernetes propagates changes. If you want to ensure that Seldon Enterprise Platform definitely has the latest changes, you can restart it using:

hashtag
Adding Policies

To add a new policy you can run:

The arguments target_groups and target_users can take multiple entries.

hashtag
Deleting Policies

Similarly to adding, to remove an existing policy you can run:

hashtag
Limitations

Using a ConfigMap for the policy file is flexible and easy to setup. However, it comes with a limitation which is true for all Kubernetes resources - it is , since that is the underlying etcd value limit.

If your use case requires a bigger size for the policy file consider mounting the file from somewhere else like an object store (S3, minio), or a database.

We are working on improving support for such use cases, which should be available in a future release.

hashtag
Migrating From Namespace Labels

To migrate from using namespace labels for defining access requirements to a namespace you can use the following command:

It will create a ConfigMap called seldon-deploy-policies in the seldon-system namespace if one is not present. The name and namespace are configurable by flags. It will then populate policies corresponding to the namespace labels in the cluster. The command will not delete any existing policies in the ConfigMap.

To confirm the change has been successful you can check the ConfigMap by running:

hashtag
Namespace Labels

circle-exclamation

This approach has been deprecated and will be removed in the future. For a more complete and efficient authorization solution, please use .

Label-based and OPA policy-based authorization cannot be used at the same time. Attempts to do so will result in only OPA policies taking effect.

Seldon Enterprise Platform can use labels on Kubernetes namespaces to determine if a user has access to resources within that namespace. Note that namespace labels can only be used for authorizing access to namespaces, but not to projects.

To authorize a user or a group to access resources in a namespace, add labels in the following manner along with the associated permission.

As an example, setting permissions on a namespace for user alice, service account sd_api and group ml_engineer would involve adding labels as follows,

circle-info

Note:Service accounts are also treated as users for authorization purposes and the service account user identity can be configured using a separate token claim if needed.

hashtag
Authorization Outside Seldon Enterprise Platform

Seldon Enterprise Platform runs in a Kubernetes platform which contains several other components. Access to these components should also be controlled. How this is done can vary based on your requirements and pre-existing access controls.

hashtag
Seldon Core

circle-info

Note:This feature is only supported in Core v1 as of now and requires Istio to be installed in the cluster.

One of the main features of Seldon Enterprise Platform is the ability to create Seldon Core deployments and allow users to make requests to these deployments. For requests to be made in a secure manner, these endpoints need to be authorized appropriately.

Seldon Enterprise Platform can automatically synchronize Istio authorization policies based on the permissions set in its OPA policies. Please refer to the for enabling this functionality.

This functionality is controlled by the rbac.opa.istioPolicySyncInterval Helm variable. You can enable synchronization by supplying a strictly positive value compatible with Go's time.ParseDuration . Using any other value, such as a negative duration or leaving the Helm parameter empty, will disable this functionality. To use the suggested interval of 5 minutes, please set the following in install-values.yaml:

Alternatively, the access to these endpoints can be manually controlled via the Istio configuration as described in the .

circle-info

Seldon Enterprise Platform provides the ability to proxy requests to Seldon Core deployments via its API. If these requests go through Seldon Enterprise Platform, then they will already be authorized based on the user's permissions.

However, it is not recommended to do this except for testing and debugging purposes, as Seldon Enterprise Platform is not designed as a high-performance proxy and cannot be configured as one. For reasons of latency, scalability, and availability you should use dedicated networking infrastructure like an ingress controller or service mesh.

hashtag
Other Components

As part of the , other components can be installed in your environment. Please refer to the official documentation for each such technology for details on how to configure authorization for them.

hashtag
Configuration Reference

The full list of Helm values for authorization is given below. These can be set in install-values.yaml. Please refer to the above documentation for how to configure each setting.

name % iris

name=iris AND version=2.0

(name=iris AND version=2.0) OR version=3.0

metrics[metricName] > 1.0 AND tags[tagKey] != someValue
<yourSeldonDomain>/seldon-deploy/api/v1alpha1/model/metadata?query=(version=1.0)
,
UNKNOWN
,
XGBOOST

"resource": "project/dev*"

"resource": "name*/seldon"

technical termarrow-up-right
herearrow-up-right
Namespace-scoped resources
Project-scoped resources
Model Catalog
System resources
OPA policies
Namespace labels
resource scopes
OPAarrow-up-right
installation guide
label-based authorization
detect them
API documentation
installation guide
examples
scope
seldon-deploy-resources repositoryarrow-up-right
API documentation
limited to 1MB sizearrow-up-right
Open Policy Agent policies
production installation guide
functionarrow-up-right
Seldon Core documentationarrow-up-right
production installation
env:
  USERID_CLAIM_KEY: "preferred_username"
  SA_ID_CLAIM_KEY: "preferred_username"
env:
  GROUPS_CLAIM_KEY: "groups"
"project.seldon.io/<name of component in graph>": "<name of project>"
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  name: mock-deployment
  namespace: seldon-deployments
spec:
  name: mock-example
  predictors:
  - name: default
    annotations:
      project.seldon.io/mock-example-container: project-a
    graph:
      name: mock-example-container
      type: MODEL
    componentSpecs:
    - spec:
        containers:
        - name: mock-example-container
          image: "seldonio/mock_classifier:1.5.0"
apiVersion: mlops.seldon.io/v1alpha1
kind: Model
metadata:
  name: iris
  namespace: seldon-deployments
  annotations:
    seldon.io/project: project-a
spec:
  storageUri: "gs://seldon-models/mlserver/iris"
  requirements:
  - sklearn
  memory: 100Ki
rbac:
  opa:
    enabled: true

  nsLabelsAuth:
    enabled: false
rbac:
  opa:
    projectAuthEnabled: true
rbac:
  opa:
    permissionManagementAPIDisabled: true
{
  "role_grants": {
    "<group name>": [
      {
        "resource": "<resource>",
        "action":   "<action>"
      },
      // More permissions for this group
    ],
    // More groups
  },
  "user_grants": {
    "<user name>": [
      {
        "resource": "<resource>",
        "action":   "<action>"
      },
      // More permissions for this user
    ],
    // More users
  }
}
{
  "action": "read",
  "resource": "namespace/seldon"
}
{
  "user_grants": {},
  "role_grants": {
    // ...
  }
}
{
  "user_grants": {
    // ...
  },
  "role_grants": {}
}
{
  "role_grants": {},
  "user_grants": {
    "*": [
      {
        "action": "read",
        "resource": "project/default"
      },
      {
        "action": "write",
        "resource": "project/default"
      }
    ]
  }
}
{
  "role_grants": {
    "data-scientist": [
      {
        "action": "read",
        "resource": "namespace/prod"
      },
      {
        "action": "write",
        "resource": "namespace/prod"
      }
    ]
  },
  "user_grants": {}
}
{
  "role_grants": {},
  "user_grants": {
    "alice": [
      {
        "action": "read",
        "resource": "system/iam"
      },
      {
        "action": "write",
        "resource": "system/iam"
      }
    ]
  }
}
{
  "role_grants": {
    "data_scientist": [
      {
        "action": "read",
        "resource": "project/iris"
      },
      {
        "action": "write",
        "resource": "project/iris"
      },
      {
        "action": "read",
        "resource": "namespace/seldon"
      }
    ],
    "ml_engineer": [
      {
        "action": "read",
        "resource": "project/iris"
      },
      {
        "action": "write",
        "resource": "project/iris"
      },
      {
        "action": "read",
        "resource": "namespace/seldon"
      },
      {
        "action": "write",
        "resource": "namespace/seldon"
      }
    ],
    "ops": [
      {
        "action": "read",
        "resource": "namespace/seldon*"
      },
      {
        "action": "read",
        "resource": "project/*"
      }
    ]
  },
  "user_grants": {
    "*": [
      {
        "action": "read",
        "resource": "project/default"
      },
      {
        "action": "write",
        "resource": "project/default"
      },
      {
        "action": "read",
        "resource": "namespace/default"
      },
      {
        "action": "write",
        "resource": "namespace/default"
      }
    ],
    "alice": [
      {
        "action": "read",
        "resource": "namespace/alice"
      },
      {
        "action": "write",
        "resource": "namespace/alice"
      }
    ]
  }
}
kubectl -n seldon-system create configmap seldon-deploy-policies --from-file=data=policy.json --dry-run=client -o yaml > policy.yaml
  kubectl apply -f policy.yaml
kubectl -n seldon-system rollout restart deployment seldon-deploy
policy_client addPolicy --resource=namespace/seldon --action=write --target_users=alice --target_groups=admin
policy_client removePolicy --resource=namespace/seldon --action=write --target_users=alice --target_groups=admin
policy_client sync
kubectl get cm -n seldon-system seldon-deploy-policies -o jsonpath='{.data.data}' | jq
seldon.user.<user name>: "write"
seldon.group.<group name>: "read"
seldon.user.alice: "write"
seldon.user.sd_api: "read"
seldon.group.ml_engineer: "read"
rbac:
  opa:
    istioPolicySyncInterval: "5m"
rbac:
  opa:
    enabled: true
    projectAuthEnabled: true
    permissionManagementAPIDisabled: false
    istioPolicySyncInterval: ""
    configMap: seldon-deploy-policies
  nsLabelsAuth:
    enabled: false

Storage Initializers

circle-info

Note: Managing secrets directly in Kubernetes is still supported, but the recommended approach is to use Enterprise Platform's secrets management tooling.

Some features in Seldon Enterprise Platform require access to external storage providers, for example, to run batch jobs.

A storage initializer mechanism similar to the one used for Prepackaged Model Serversarrow-up-right is used by Seldon Enterprise Platform. By default, Seldon Enterprise Platform uses the Rclone-based storage initializerarrow-up-right. Rclonearrow-up-right offers compatibility with over 40 different cloud storage products and is therefore a sensible default.

However, custom storage initializers may be used by modifying the storageInitializer values in install-values.yaml.

hashtag
Configuration

Rclone storage initializers are configured using environmental variables passed as secrets in Seldon Enterprise Platform. These are configured per namespace.

Each remote storage provider needs to be configured using environment variables that follow the following pattern:

circle-info

Note: Multiple remotes can be configured simultaneously. For example, both s3 (AWS S3) and gs (Google Cloud Storage) remotes can be configured for the same storage initializer.

Once the remote is configured, the modelUri that is compatible with rclone takes the form:

For example modelUri: minio:sklearn/iris, or modelUri: gs:seldon-models/cifar10. Rclone will remove the leading slashes for buckets so this is equivalent to minio://sklearn/iris or gs://seldon-models/cifar10.

Below you will find a few example configurations. For other storage providers, please consult the .

Please note that you need the labels secret-type: bucket and seldon-deploy: "true" on your secret for it to be correctly picked up by Enterprise Platform. Without these labels it will not show in the secrets dropdown in the deployment creation wizard.

hashtag
MinIO

This is an example of how to set up secrets so that Rclone may access .

Reference:

hashtag
Public GCS configuration

circle-info

This is configured by default in the seldonio/rclone-storage-initializer image.

Reference: .

hashtag
AWS S3 with access key and secret

Reference:

hashtag
Example AWS S3 with IAM roles configuration

Reference:

hashtag
GCP/GKE

Reference:

For GCP/GKE, you will need create a service-account key and save it as a local json file.

First make sure that you have a gcloud service account ([SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com) that has sufficient permissions to access the bucket with your models (i.e. Storage Object Admin). You can check this using the .

Next, generate keys locally using the gcloud tool. This will create your service-account key file at gcloud-application-credentials.json:

Use the content of the locally saved gcloud-application-credentials.json file to create the rclone secret:

circle-info

The remote name is gcs here so urls would take form similar to gcs:<your bucket>.

hashtag
Custom Storage Initializer

If for some reason you would like to use a different storage initializer for batch jobs, e.g. KFServing storage initializer, you can set this by modifying install-values.yaml:

The corresponding secret for would also need to be created:

Rclone documentationarrow-up-right
MinIO as configured in the production installation
Rclone documentationarrow-up-right
Rclone documentationarrow-up-right
Rclone documentationarrow-up-right
Rclone documentationarrow-up-right
Rclone documentationarrow-up-right
gcloud consolearrow-up-right
MinIO as configured in the production installation
RCLONE_CONFIG_<remote name>_<config variable>: <config value>
modelUri: <remote>:<bucket name>
export MINIONAMESPACE=minio-system
export MINIOUSER=minioadmin
export MINIOPASSWORD=minioadmin
export NAMESPACE=seldon

cat << EOF > seldon-rclone-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: minio-bucket
  labels:
    secret-type: bucket
    seldon-deploy: "true"
type: Opaque
stringData:
  RCLONE_CONFIG_S3_TYPE: s3
  RCLONE_CONFIG_S3_PROVIDER: minio
  RCLONE_CONFIG_S3_ENV_AUTH: "false"
  RCLONE_CONFIG_S3_ACCESS_KEY_ID: ${MINIOUSER}
  RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: ${MINIOPASSWORD}
  RCLONE_CONFIG_S3_ENDPOINT: http://minio.${MINIONAMESPACE}.svc.cluster.local:9000
EOF

kubectl apply -n ${NAMESPACE} -f minio-bucket.yaml
apiVersion: v1
kind: Secret
metadata:
  name: gs-bucket
  labels:
    secret-type: bucket
    seldon-deploy: "true"
type: Opaque
stringData:
  RCLONE_CONFIG_GS_TYPE: google cloud storage
  RCLONE_CONFIG_GS_ANONYMOUS: "true"
apiVersion: v1
kind: Secret
metadata:
  name: s3-bucket
  labels:
    secret-type: bucket
    seldon-deploy: "true"
type: Opaque
stringData:
  RCLONE_CONFIG_S3_TYPE: s3
  RCLONE_CONFIG_S3_PROVIDER: aws
  RCLONE_CONFIG_S3_ENV_AUTH: "false"
  RCLONE_CONFIG_S3_ACCESS_KEY_ID: "<your AWS_ACCESS_KEY_ID here>"
  RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: "<your AWS_SECRET_ACCESS_KEY here>"
apiVersion: v1
kind: Secret
metadata:
  name: s3-bucket
  labels:
    secret-type: bucket
    seldon-deploy: "true"
type: Opaque
stringData:
  RCLONE_CONFIG_S3_TYPE: s3
  RCLONE_CONFIG_S3_PROVIDER: aws
  RCLONE_CONFIG_S3_ACCESS_KEY_ID: ""
  RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: ""
  RCLONE_CONFIG_S3_ENV_AUTH: "true"
gcloud iam service-accounts keys create gcloud-application-credentials.json --iam-account [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com
apiVersion: v1
kind: Secret
metadata:
  name: gcs-bucket
  labels:
    secret-type: bucket
    seldon-deploy: "true"
type: Opaque
stringData:
  RCLONE_CONFIG_GCS_TYPE: google cloud storage
  RCLONE_CONFIG_GCS_ANONYMOUS: "false"
  RCLONE_CONFIG_GCS_SERVICE_ACCOUNT_CREDENTIALS: '{"type":"service_account", ... <rest of gcloud-application-credentials.json>}'
batchjobs:
  storageInitializer:
    image: gcr.io/kfserving/storage-initializer:v0.4.0
export MINIOUSER=minioadmin
export MINIOPASSWORD=minioadmin
export NAMESPACE=seldon

cat << EOF > seldon-kfserving-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: seldon-kfserving-secret
type: Opaque
stringData:
  AWS_ACCESS_KEY_ID: ${MINIOUSER}
  AWS_SECRET_ACCESS_KEY: ${MINIOPASSWORD}
  AWS_ENDPOINT_URL: http://minio.minio-system.svc.cluster.local:9000
  USE_SSL: "false"
EOF

kubectl apply -n ${NAMESPACE} -f seldon-kfserving-secret.yaml