Skip to main content
Version: v0.64.0

Create secure deployments

This example demonstrates how you can create three experiments and deploy them in the three security modes supported by MLOps.

Before you begin
  • Install Driverless AI and launch a new instance of Driverless AI.
  • Install bcrypt.
  • You will need the values for the following constants in order to successfully carry out the task. Contact your administrator to obtain deployment specific values.
ConstantValueDescription
MLOPS_API_URLUsually: https://api.mlops.my.domainDefines the URL for the MLOps Gateway component. You can verify the correct URL by navigating to the API URL in your browser. It should provide a page with a list of available routes.
TOKEN_ENDPOINT_URL
https://mlops.keycloak.domain/auth/realms/[fill-in-realm-name]/protocol/openid-connect/token
Defines the token endpoint URL of the Identity Provider. This uses Keycloak as the Identity Provider. Keycloak Realm should be provided.
REFRESH_TOKEN<your-refresh-token>Defines the user's refresh token
CLIENT_ID<your-client-id>Sets the client id for authentication. This is the client you will be using to connect to MLOps.
DRIVERLESS_URL<your-dai-instance-url>Defines the URL of the Driverless AI instance you have launched.
PROJECT_NAMESecureEndpointsExampleDefines a project name that the script will be using.
EXPERIMENT_NAME_INSECURECC-Example-InsecureDefines a name for the experiment that will be created and deployed with insecure scoring endpoint with no authorization.
EXPERIMENT_NAME_SECURE_PLAINCC-Example-SecurePlainDefines a name for the experiment that will be created and deployed with secure scoring endpoint with passphrase stored as plain text.
EXPERIMENT_NAME_SECURE_HASHEDCC-Example-SecureHashedDefines a name for the experiment that will be created and deployed with secure scoring endpoint with passphrase stored as a hash.
SECURE_ENDPOINT_PASSWORDp@55w0r6Defines a password that will be used for securing scoring endpoints.
TRAIN_FILE_URL
s3://h2o-public-test-data/smalldata/kaggle/CreditCard/creditcard_train_cat.csv
Defines the training dataset.
TARGET_COLUMNDEFAULT_PAYMENT_NEXT_MONTHDefines the target column for the experiment.
DEPLOYMENT_ENVIRONMENTDEVDefines the target deployment environment.
REFRESH_STATUS_INTERVAL1.0Defines a refresh interval for the deployment health check.
MAX_WAIT_TIME300Defines maximum waiting time for the deployment to become healthy.

The following steps demonstrate how you can use MLOps Python client to create three experiments and deploy them in the three security modes supported by MLOps.

  1. Download the SecureEndpointsExample.py file.

  2. Change the values of the following constants in your SecureEndpointsExample.py file as given in the preceding data table.

    SecureEndpointsExample.py
    ### Constants
    MLOPS_API_URL = <MLOPS_API_URL>
    TOKEN_ENDPOINT_URL = <TOKEN_ENDPOINT_URL>
    REFRESH_TOKEN = <REFRESH_TOKEN>
    CLIENT_ID = <CLIENT_ID>
    DRIVERLESS_URL = <DRIVERLESS_URL>
    PROJECT_NAME = <PROJECT_NAME>
    EXPERIMENT_NAME_INSECURE = <EXPERIMENT_NAME_INSECURE>
    EXPERIMENT_NAME_SECURE_PLAIN = <EXPERIMENT_NAME_SECURE_PLAIN>
    EXPERIMENT_NAME_SECURE_HASHED = <EXPERIMENT_NAME_SECURE_HASHED>
    SECURE_ENDPOINT_PASSWORD = <SECURE_ENDPOINT_PASSWORD>
    TRAIN_FILE_URL = <TRAIN_FILE_URL>
    TARGET_COLUMN = <TARGET_COLUMN>
    DEPLOYMENT_ENVIRONMENT = <DEPLOYMENT_ENVIRONMENT>
    REFRESH_STATUS_INTERVAL = <REFRESH_STATUS_INTERVAL>
    MAX_WAIT_TIME = <MAX_WAIT_TIME>
    SecureEndpointsExample.py
    ### Constants
    MLOPS_API_URL = "https://api.mlops.my.domain"
    TOKEN_ENDPOINT_URL="https://mlops.keycloak.domain/auth/realms/[fill-in-realm-name]/protocol/openid-connect/token"
    REFRESH_TOKEN="<your-refresh-token>"
    CLIENT_ID="<your-mlops-client>"
    DRIVERLESS_URL = "<your-dai-instance-url>"
    PROJECT_NAME = "SecureEndpointsExample"
    EXPERIMENT_NAME_INSECURE = "CC-Example-Insecure"
    EXPERIMENT_NAME_SECURE_PLAIN = "CC-Example-SecurePlain"
    EXPERIMENT_NAME_SECURE_HASHED = "CC-Example-SecureHashed"
    SECURE_ENDPOINT_PASSWORD = "p@55w0r6"
    TRAIN_FILE_URL = "s3://h2o-public-test-data/smalldata/kaggle/CreditCard/creditcard_train_cat.csv"
    TARGET_COLUMN = "DEFAULT_PAYMENT_NEXT_MONTH"
    DEPLOYMENT_ENVIRONMENT = "DEV"
    REFRESH_STATUS_INTERVAL = 1.0
    MAX_WAIT_TIME = 300
  3. Run the SecureEndpointsExample.py file.

    python3 SecureEndpointsExample.py
    Experiment launched at: <your-dai-url>/#/experiment?key=05a0e29e-17f0-11ed-8fb0-22e31155f87d
    Complete 100.00% - Status: Complete
    INSECURE SCORING ENDPOINT: {'fields': ['DEFAULT_PAYMENT_NEXT_MONTH.0', 'DEFAULT_PAYMENT_NEXT_MONTH.1'], 'id': '05a0e29e-17f0-11ed-8fb0-22e31155f87d', 'score': [['0.65685487', '0.34314513']]}
    Experiment launched at: <your-dai-url>/#/experiment?key=6e37a342-17f0-11ed-8fb0-22e31155f87d
    Complete 100.00% - Status: Complete
    SECURED WITH PLAIN PASSPHRASE SCORING ENDPOINT: {'fields': ['DEFAULT_PAYMENT_NEXT_MONTH.0', 'DEFAULT_PAYMENT_NEXT_MONTH.1'], 'id': '6e37a342-17f0-11ed-8fb0-22e31155f87d', 'score': [['0.7408047', '0.2591953']]}
    Experiment launched at: <your-dai-url>/#/experiment?key=da3c95c0-17f0-11ed-8fb0-22e31155f87d
    Complete 100.00% - Status: Complete
    SECURED WITH HASHED PASSPHRASE SCORING ENDPOINT: {'fields': ['DEFAULT_PAYMENT_NEXT_MONTH.0', 'DEFAULT_PAYMENT_NEXT_MONTH.1'], 'id': 'da3c95c0-17f0-11ed-8fb0-22e31155f87d', 'score': [['0.6093691', '0.3906309']]}
  4. Navigate to MLOps and click the project name SecureEndpointsExample under Projects to view the deployed models.

    Create secure endpoints - all experiments

    Note

    For more information about model deployments in MLOps, see Understand deployments in MLOps.

  5. Click each deployment to view the Deployment Overview panel, which contains deployment details and security details.

    Note

    For more information about the Deployment Overview panel, see Understanding the Deployment Overview window.

Example walkthrough

The following steps provide a walkthrough of each of the sections in the SecureEndpointsExample.py file.

  1. Include the following function, which finds the artifact IDs for a given experiment.

    SecureEndpointsExample.py
    def find_artifact_id_for_experiment(mlops_client: mlops.Client, key: str):
    artifact_list = mlops_client.storage.artifact.list_entity_artifacts(
    mlops.StorageListEntityArtifactsRequest(entity_id=key)
    ).artifact

    for ar in artifact_list:
    if ar.type == "dai/mojo_pipeline":
    return ar.id
    else:
    raise LookupError(f"Could not find 'dai/mojo_pipeline' artifact.")
  2. Include the helper function, which waits for the deployment to become healthy.

  3. Include the following function, which generates a hashed password using bcrypt.

    SecureEndpointsExample.py
    def hash_password(password: str) -> str:
    salt = bcrypt.gensalt(
    rounds=12, prefix=b"2a"
    ) # number of rounds and prefix are constants set for the entire MLOps platform
    hashed = bcrypt.hashpw(password.encode(), salt)
    return hashed.decode()
  4. Set up the token provider using an existing refresh token.

  5. Set up the Driverless AI client.

    SecureEndpointsExample.py
    dai_client = driverlessai.Client(
    address=DRIVERLESS_URL, token_provider=mlops_token_provider
    )
  6. Set up the MLOps client.

  7. Create a project in Driverless AI. Then fetch the credit card dataset from S3 and link the dataset to the created project.

    SecureEndpointsExample.py
    # Creating a project in DAI.
    prj = dai_client.projects.create(PROJECT_NAME)

    # Fetching the credit card dataset from S3.
    ds_train = dai_client.datasets.create_async(
    data=TRAIN_FILE_URL, data_source="s3"
    ).result(silent=True)

    # Linking the dataset to the project.
    prj.link_dataset(ds_train, dataset_type="train_dataset")
  8. Fetch the available deployment environments and look up the ID of the selected deployment environment.

  9. Create three experiments and deploy them in the supported security configurations.

    1. Insecure scoring endpoint with no authorization

    1. Create the experiment exp_insecure and link the experiment to the project prj created in step 7.

      SecureEndpointsExample.py
      exp_insecure = dai_client.experiments.create(
      name=EXPERIMENT_NAME_INSECURE,
      train_dataset=ds_train,
      target_column=TARGET_COLUMN,
      task="classification",
      accuracy=1,
      time=1,
      interpretability=1,
      scorer="AUC",
      enable_gpus=False,
      seed=1234,
      cols_to_drop=["ID"],
      )

      # Linking an experiment to the project.
      prj.link_experiment(exp_insecure)
    2. Look for the ID of the artifact to deploy.

      SecureEndpointsExample.py
      artifact_id_insecure = find_artifact_id_for_experiment(
      mlops_client=mlops_client, key=exp_insecure.key
      )
    3. Customize the composition of the deployment and specify the deployment as a single deployment with no security protocols.

      SecureEndpointsExample.py
      # Customize the composition of the deployment
      composition = mlops.DeployDeploymentComposition(
      experiment_id=exp_insecure.key,
      artifact_id=artifact_id_insecure,
      deployable_artifact_type_name="dai/mojo_pipeline",
      artifact_processor_name="dai_mojo_pipeline_extractor",
      runtime_name="dai_mojo_runtime"
      )

      # Specify the deployment as a single deployment with no security protocols
      to_deploy = mlops.DeployDeployment(
      project_id=prj.key,
      deployment_environment_id=deployment_env_id,
      single_deployment=mlops.DeploySingleDeployment(
      deployment_composition=composition
      ),
      )
    4. Send a deployment request to create an insecure endpoint and wait for the deployment to become healthy.

      SecureEndpointsExample.py
      # Sending a deployment request for creating an insecure endpoint.
      deployment_insecure: mlops.DeployDeployment = mlops_client.deployer.deployment.create_deployment(
      mlops.DeployCreateDeploymentRequest(deployment=to_deploy)
      ).deployment

      # Waiting for the deployment to become healthy.
      deployment_status = deployment_should_become_healthy(
      mlops_client, deployment_insecure.id
      )
      if deployment_status.state != mlops.DeployDeploymentState.HEALTHY:
      print(
      f"Deployment still not healthy after max wait time with state: {deployment_status.state}"
      )
    5. Get the status and properties of the deployment and create a sample request.

      SecureEndpointsExample.py
      # Getting deployment's status and properties.
      status_insecure: mlops.DeployDeploymentStatus = (
      mlops_client.deployer.deployment_status.get_deployment_status(
      mlops.DeployGetDeploymentStatusRequest(deployment_insecure.id)
      )
      ).deployment_status

      # Getting sample request for the deployment and sending a scoring request.
      sample_data = request.urlopen(status_insecure.scorer.sample_request.url).read()
    6. Finally, send a sample request.

      SecureEndpointsExample.py
      req = request.Request(
      status_insecure.scorer.score.url,
      method=status_insecure.scorer.score.method,
      headers={"Content-Type": "application/json"},
      )
      resp = request.urlopen(req, sample_data).read()
      print("INSECURE SCORING ENDPOINT:", json.loads(resp))

    2. Secure scoring endpoint with passphrase stored as plain text

    1. Create the experiment exp_secure_plain and link the experiment to the project prj created in step 7.

      SecureEndpointsExample.py
      exp_secure_plain = dai_client.experiments.create(
      name=EXPERIMENT_NAME_SECURE_PLAIN,
      train_dataset=ds_train,
      target_column=TARGET_COLUMN,
      task="classification",
      accuracy=1,
      time=1,
      interpretability=1,
      scorer="AUC",
      enable_gpus=False,
      seed=1234,
      cols_to_drop=["ID"],
      )

      # Linking an experiment to the project.
      prj.link_experiment(exp_secure_plain)
    2. Look for the ID of the artifact to deploy.

      SecureEndpointsExample.py
      artifact_id_secure_plain = find_artifact_id_for_experiment(
      mlops_client=mlops_client, key=exp_secure_plain.key
      )
    3. Customize the composition of the deployment and specify the deployment as a single deployment with passphrase stored as plain text.

      SecureEndpointsExample.py
      # Customize the composition of the deployment
      composition = mlops.DeployDeploymentComposition(
      experiment_id=exp_secure_plain.key,
      artifact_id=artifact_id_secure_plain,
      deployable_artifact_type_name="dai/mojo_pipeline",
      artifact_processor_name="dai_mojo_pipeline_extractor",
      runtime_name="dai_mojo_runtime"
      )

      # Specify the deployment as a single deployment with passphrase stored as plain text.
      to_deploy = mlops.DeployDeployment(
      project_id=prj.key,
      deployment_environment_id=deployment_env_id,
      single_deployment=mlops.DeploySingleDeployment(
      deployment_composition=composition
      ),
      security=mlops.DeploySecurity(
      passphrase=mlops.DeployAuthenticationPassphrase(
      hash=SECURE_ENDPOINT_PASSWORD,
      passphrase_hash_type=mlops.DeployPassphraseHashType.PLAINTEXT,
      )
      )
      )
    4. Send a deployment request to create a secure endpoint without password hashing and wait for the deployment to become healthy.

      SecureEndpointsExample.py
      # Sending a deployment request for creating a secure endpoint without password hashing.
      deployment_secure_plain: mlops.DeployDeployment = mlops_client.deployer.deployment.create_deployment(
      mlops.DeployCreateDeploymentRequest(deployment=to_deploy)
      ).deployment

      # Waiting for the deployment to become healthy.
      deployment_status = deployment_should_become_healthy(
      mlops_client, deployment_secure_plain.id
      )
      if deployment_status.state != mlops.DeployDeploymentState.HEALTHY:
      print(
      f"Deployment still not healthy after max wait time with state: {deployment_status.state}"
      )
    5. Get the status and properties of the deployment and create a sample request.

      SecureEndpointsExample.py
      # Getting deployment's status and properties.
      status_secure_plain: mlops.DeployDeploymentStatus = (
      mlops_client.deployer.deployment_status.get_deployment_status(
      mlops.DeployGetDeploymentStatusRequest(deployment_secure_plain.id)
      )
      ).deployment_status

      # Getting sample request for the deployment and sending a scoring request.
      req = request.Request(status_secure_plain.scorer.sample_request.url)
      req.add_header("Authorization", f"Bearer {SECURE_ENDPOINT_PASSWORD}")
      sample_data = request.urlopen(req).read()
    6. Finally, send a sample request.

      SecureEndpointsExample.py
      req = request.Request(
      status_secure_plain.scorer.score.url,
      method=status_secure_plain.scorer.score.method,
      headers={
      "Content-Type": "application/json",
      "Authorization": f"Bearer {SECURE_ENDPOINT_PASSWORD}",
      },
      )
      resp = request.urlopen(req, sample_data).read()
      print("SECURED WITH PLAIN PASSPHRASE SCORING ENDPOINT:", json.loads(resp))

    3. Secure scoring endpoint with passphrase stored as a hash

    1. Create the experiment exp_secure_hashed and link the experiment to the project prj created in step 7.

      SecureEndpointsExample.py
      exp_secure_hashed = dai_client.experiments.create(
      name=EXPERIMENT_NAME_SECURE_HASHED,
      train_dataset=ds_train,
      target_column=TARGET_COLUMN,
      task="classification",
      accuracy=1,
      time=1,
      interpretability=1,
      scorer="AUC",
      enable_gpus=False,
      seed=1234,
      cols_to_drop=["ID"],
      )

      # Linking an experiment to the project.
      prj.link_experiment(exp_secure_hashed)
    2. Look for the ID of the artifact to deploy.

      SecureEndpointsExample.py
      artifact_id_secure_hashed = find_artifact_id_for_experiment(
      mlops_client=mlops_client, key=exp_secure_hashed.key
      )
    3. Customize the composition of the deployment and specify the deployment as a single deployment with passphrase stored as a hash.

      SecureEndpointsExample.py
      # Customize the composition of the deployment
      composition = mlops.DeployDeploymentComposition(
      experiment_id=exp_secure_hashed.key,
      artifact_id=artifact_id_secure_hashed,
      deployable_artifact_type_name="dai/mojo_pipeline",
      artifact_processor_name="dai_mojo_pipeline_extractor",
      runtime_name="dai_mojo_runtime"
      )

      # Specify the deployment as a single deployment with passphrase stored as a hash.
      to_deploy = mlops.DeployDeployment(
      project_id=prj.key,
      deployment_environment_id=deployment_env_id,
      single_deployment=mlops.DeploySingleDeployment(
      deployment_composition=composition
      ),
      security=mlops.DeploySecurity(
      passphrase=mlops.DeployAuthenticationPassphrase(
      hash=hash_password(SECURE_ENDPOINT_PASSWORD),
      passphrase_hash_type=mlops.DeployPassphraseHashType.BCRYPT,
      )
      )
      )
    4. Send a deployment request to create a secure endpoint with password hashing and wait for the deployment to become healthy.

      SecureEndpointsExample.py
      # Sending a deployment request for creating a secure endpoint with password hashing.
      deployment_secure_hashed: mlops.DeployDeployment = mlops_client.deployer.deployment.create_deployment(
      mlops.DeployCreateDeploymentRequest(deployment=to_deploy)
      ).deployment

      # Waiting for the deployment to become healthy.
      deployment_status = deployment_should_become_healthy(
      mlops_client, deployment_secure_hashed.id
      )
      if deployment_status.state != mlops.DeployDeploymentState.HEALTHY:
      print(
      f"Deployment still not healthy after max wait time with state: {deployment_status.state}"
      )
    5. Get the status and properties of the deployment and create a sample request.

      SecureEndpointsExample.py
      # Getting deployment's status and properties.
      status_secure_hashed: mlops.DeployDeploymentStatus = (
      mlops_client.deployer.deployment_status.get_deployment_status(
      mlops.DeployGetDeploymentStatusRequest(deployment_secure_hashed.id)
      )
      ).deployment_status

      # Getting sample request for the deployment and sending a scoring request.
      req = request.Request(status_secure_hashed.scorer.sample_request.url)
      req.add_header("Authorization", f"Bearer {SECURE_ENDPOINT_PASSWORD}")
      sample_data = request.urlopen(req).read()
    6. Finally, send a sample request.

      SecureEndpointsExample.py
      req = request.Request(
      status_secure_hashed.scorer.score.url,
      method=status_secure_hashed.scorer.score.method,
      headers={
      "Content-Type": "application/json",
      "Authorization": f"Bearer {SECURE_ENDPOINT_PASSWORD}",
      },
      )
      resp = request.urlopen(req, sample_data).read()
      print("SECURED WITH HASHED PASSPHRASE SCORING ENDPOINT:", json.loads(resp))

Feedback