Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"execute-api:/*"
]
},
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"execute-api:/*"
],
"Condition" : {
"StringNotEquals": {
"aws:SourceVpce": [
"vpce-1a2b3c4d5e6f7g8h9", # customer internal VPC Endpoint
"vpce-0421446f7bf694e56" # Immuta VPC Endpoint added to list
]
}
}
}
]
{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:****************/foo/GET/bar with an explicit deny"}
"private_access_settings_name": "immuta-access",
"region": "us-east-1",
"public_access_enabled": false,
"private_access_level": "ENDPOINT",
"allowed_vpc_endpoint_ids": [
"vpce-0fe5b17a0707d6fa5"
]
privatelink-account-urlSynapse workspace -> Settings -> Properties and getting the Resource ID)

eu-west-2c

privatelink.immutacloud.com DNS

select SYSTEM$GET_PRIVATELINK_CONFIG()SELECT SYSTEM$AUTHORIZE_PRIVATELINK (
'/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Network/privateEndpoints/abc12345.east-us-2.azure.snowflakecomputing.com-eus2',
'<ACCESS_TOKEN>'
);.localTLD, Immuta cannot verify that they own it because it's impossible to have exclusive ownership over a private TLD. If Company B also uses a .local TLD, it becomes impossible to determine what the canonical trust chain for either company's private CA is.eu-west-2c


select SYSTEM$GET_PRIVATELINK_CONFIG()


#!/bin/bash
# Script to connect a GCP PSC endpoint to a Databricks account by
# impersonating a service account and retrieving tokens.
#
# Usage:
# ./accept-databricks-psc.sh -s SERVICE_ACCOUNT_EMAIL \
# -d DATABRICKS_ACCOUNT_ID \
# -e ENDPOINT_NAME \
# -r ENDPOINT_REGION \
# -p PROJECT_ID \
# [OPTIONS]
#
# Example:
# ./accept-databricks-psc.sh -s [email protected] \
# -d 12345678-90ab-cdef-1234-567890abcdef \
# -e dbx-company-project-region \
# -r us-east4 \
# -p my-gcp-project \
# -j # (with JSON logging)
set -euo pipefail
# Default values
LOG_FORMAT="text"
# Function to display usage
usage() {
cat << EOF
Usage: $0 -s SERVICE_ACCOUNT_EMAIL [OPTIONS]
Verify gcloud setup and service account impersonation, retrieving access and ID tokens.
Required:
-s SERVICE_ACCOUNT Service account email to impersonate
-d DATABRICKS_ACCOUNT_ID Databricks account ID (UUID format)
-e ENDPOINT_NAME Name of the VPC endpoint to attach (e.g., "dbx-company-project-region")
-r ENDPOINT_REGION Region where the VPC endpoint is located (e.g., "us-east4")
-p PROJECT_ID GCP project ID where the VPC endpoint is located (Immuta's SaaS project ID)
Options:
-h Show this help message
-j Enable JSON logging format
-D DATABRICKS_ENDPOINT_NAME Databricks Endpoint Name (defaults to "immuta-<region>-psc-endpoint")
Example:
# Basic usage
$0 -s [email protected] \
-d 12345678-90ab-cdef-1234-567890abcdef \
-e dbx-company-project-region \
-r us-east4 \
-p immuta-gcp-project
EOF
}
DATABRICKS_ENDPOINT_NAME=""
# Parse command line arguments
while getopts "s:d:e:r:p:D:jh" opt; do
case ${opt} in
s)
SERVICE_ACCOUNT="${OPTARG}"
;;
d)
DATABRICKS_ACCOUNT_ID="${OPTARG}"
;;
e)
ENDPOINT_NAME="${OPTARG}"
;;
r)
ENDPOINT_REGION="${OPTARG}"
;;
p)
PROJECT_ID="${OPTARG}"
;;
D)
DATABRICKS_ENDPOINT_NAME="${OPTARG}"
;;
j)
LOG_FORMAT="json"
;;
h)
usage
exit 0
;;
\?)
echo "Error: Invalid option -${OPTARG}" >&2
echo "Run '$0 -h' for usage information"
exit 1
;;
:)
echo "Error: Option -${OPTARG} requires an argument" >&2
exit 1
;;
esac
done
# Check if service account was provided
if [[ -z "${SERVICE_ACCOUNT:-}" ]]; then
echo "Error: Service account email is required"
usage
exit 1
fi
# Check if Databricks account ID was provided
if [[ -z "${DATABRICKS_ACCOUNT_ID:-}" ]]; then
echo "Error: Databricks account ID is required"
usage
exit 1
fi
# Check if VPC endpoint name was provided
if [[ -z "${ENDPOINT_NAME:-}" ]]; then
echo "Error: VPC endpoint name is required"
usage
exit 1
fi
# Check if VPC endpoint region was provided
if [[ -z "${ENDPOINT_REGION:-}" ]]; then
echo "Error: VPC endpoint region is required"
usage
exit 1
fi
# Check if GCP project ID was provided
if [[ -z "${PROJECT_ID:-}" ]]; then
echo "Error: GCP project ID is required"
usage
exit 1
fi
# Check if Databricks endpoint name was provided, if not set default name
if [[ -z "${DATABRICKS_ENDPOINT_NAME:-}" ]]; then
DATABRICKS_ENDPOINT_NAME="immuta-${ENDPOINT_REGION}-psc-endpoint"
fi
# Function to log with simplified or JSON format
log() {
local level="${1:-INFO}"
# Shift the first argument (log level) so that $* does not include the level
shift || true
local message="$*"
local timestamp
# Use portable date format (macOS date doesn't support %N)
if date --version &>/dev/null; then
# GNU date
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")
else
# BSD date (macOS)
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
fi
if [[ "${LOG_FORMAT}" == "json" ]]; then
# JSON format: timestamp, level, and message (properly escaped)
jq -nc --arg ts "${timestamp}" --arg lvl "${level}" --arg msg "${message}" \
'{timestamp: $ts, level: $lvl, message: $msg}'
else
# Color codes for different log levels
local color_reset='\033[0m'
local color_level=""
case "${level}" in
INFO)
color_level='\033[0;36m' # Cyan
;;
WARN)
color_level='\033[0;33m' # Yellow
;;
ERROR)
color_level='\033[0;31m' # Red
;;
DEBUG)
color_level='\033[0;90m' # Gray
;;
*)
color_level='\033[0m' # No color
;;
esac
# Simple format with color: [timestamp] [level] message
printf "[%s] [${color_level}%s${color_reset}] %s\n" "${timestamp}" "${level}" "${message}"
fi
}
if [[ "${LOG_FORMAT}" == "json" ]]; then
log INFO "Starting Immuta Databricks GCP PSC Acceptance Script"
else
log INFO "================================================"
log INFO "Immuta Databricks GCP PSC Acceptance Script"
log INFO "================================================"
fi
log INFO "Service Account: ${SERVICE_ACCOUNT}"
log INFO "Databricks Account ID: ${DATABRICKS_ACCOUNT_ID}"
log INFO "VPC Endpoint Name: ${ENDPOINT_NAME}"
log INFO "VPC Endpoint Region: ${ENDPOINT_REGION}"
log INFO "Databricks Endpoint Name: ${DATABRICKS_ENDPOINT_NAME}"
# Step 1: Check if gcloud, curl, and jq are installed
log INFO "[1/6] Checking if dependencies are installed..."
if ! command -v gcloud &> /dev/null; then
log ERROR "β ERROR: gcloud CLI is not installed"
log ERROR " Please install it from: https://cloud.google.com/sdk/docs/install"
exit 1
fi
if ! command -v curl &> /dev/null; then
log ERROR "β ERROR: curl is not installed"
log ERROR " Please install it using your package manager (e.g., apt, yum, brew)"
exit 1
fi
if ! command -v jq &> /dev/null; then
log ERROR "β ERROR: jq is not installed"
log ERROR " Please install it using your package manager (e.g., apt, yum, brew)"
exit 1
fi
GCLOUD_VERSION=$(gcloud version --format="value(core)" 2>/dev/null || echo "unknown")
log INFO "β
gcloud is installed (version: ${GCLOUD_VERSION})"
if [[ $LOG_FORMAT != "json" ]]; then log INFO ""; fi
# Step 2: Check if user is logged in
log INFO "[2/6] Checking if you are logged in to gcloud..."
CURRENT_ACCOUNT=$(gcloud config get-value account 2>/dev/null || echo "")
if [[ -z "${CURRENT_ACCOUNT}" ]]; then
log ERROR "β ERROR: Not logged in to gcloud"
log ERROR " Run: gcloud auth login"
exit 1
fi
log INFO "β
Logged in as: ${CURRENT_ACCOUNT}"
if [[ $LOG_FORMAT != "json" ]]; then log INFO ""; fi
# Step 3: Verify impersonation by getting an access token
log INFO "[3/6] Verifying service account impersonation (access token)..."
set +e # Temporarily disable exit on error
GCLOUD_OUTPUT=$(gcloud auth print-access-token \
--impersonate-service-account="${SERVICE_ACCOUNT}" \
--verbosity=error 2>&1)
GCLOUD_EXIT=$?
set -e # Re-enable exit on error
if [[ ${GCLOUD_EXIT} -ne 0 ]]; then
log ERROR "Failed to impersonate service account for access token"
log ERROR "${GCLOUD_OUTPUT}"
# while IFS= read -r line; do
# [[ -n "${line}" ]] && log ERROR "${line}"
# done <<< "${GCLOUD_OUTPUT}"
exit 1
fi
ACCESS_TOKEN="${GCLOUD_OUTPUT}"
log INFO "β
Successfully obtained access token"
if [[ $LOG_FORMAT != "json" ]]; then log INFO ""; fi
# Step 4: Get an ID token
log INFO "[4/6] Getting ID token for service account..."
set +e # Temporarily disable exit on error
GCLOUD_OUTPUT=$(gcloud auth print-identity-token \
--impersonate-service-account="${SERVICE_ACCOUNT}" \
--include-email \
--verbosity=error \
--audiences="https://accounts.gcp.databricks.com" 2>&1)
GCLOUD_EXIT=$?
set -e # Re-enable exit on error
if [[ ${GCLOUD_EXIT} -ne 0 ]]; then
log ERROR "Failed to get ID token"
while IFS= read -r line; do
[[ -n "${line}" ]] && log ERROR "${line}"
done <<< "${GCLOUD_OUTPUT}"
exit 1
fi
ID_TOKEN="${GCLOUD_OUTPUT}"
log INFO "β
Successfully obtained ID token"
if [[ $LOG_FORMAT != "json" ]]; then log INFO ""; fi
# Step 5: List existing VPC endpoints
log INFO "[5/6] Listing existing VPC endpoints..."
if ! RESULT=$(curl -s -XGET \
--header "Authorization: Bearer ${ID_TOKEN}" \
"https://accounts.gcp.databricks.com/api/2.0/accounts/${DATABRICKS_ACCOUNT_ID}/vpc-endpoints"); then
log ERROR "β ERROR: Failed to call Databricks API to list VPC endpoints"
log ERROR " ${RESULT}"
exit 1
fi
echo "${RESULT}" | jq -er '.[] | select(.gcp_vpc_endpoint_info.psc_endpoint_name == "'"${ENDPOINT_NAME}"'")' > /dev/null && {
log ERROR "β Existing VPC endpoint found with name '${ENDPOINT_NAME}'"
log ERROR " If this is unexpected, please delete the existing endpoint in the Databricks console and try again"
exit 1
}
log INFO "β
No existing VPC endpoint with name '${ENDPOINT_NAME}' found"
if [[ $LOG_FORMAT != "json" ]]; then log INFO ""; fi
log INFO "[6/6] Creating VPC endpoint attachment..."
REQUEST=$(cat <<EOF
{
"gcp_vpc_endpoint_info": {
"endpoint_region": "${ENDPOINT_REGION}",
"project_id": "${PROJECT_ID}",
"psc_endpoint_name": "${ENDPOINT_NAME}"
},
"vpc_endpoint_name": "${DATABRICKS_ENDPOINT_NAME}"
}
EOF
)
RESULT=$(curl -s -XPOST \
-d "${REQUEST}" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${ID_TOKEN}" \
--header "X-Databricks-GCP-SA-Access-Token: ${ACCESS_TOKEN}" \
"https://accounts.gcp.databricks.com/api/2.0/accounts/${DATABRICKS_ACCOUNT_ID}/vpc-endpoints")
if [[ "$(echo "${RESULT}" | jq -r '.error_code // empty')" != "" ]]; then
log ERROR "β ERROR: Failed to create VPC endpoint attachment"
log ERROR " ${RESULT}"
exit 1
fi
# Output based on mode
if [[ "${LOG_FORMAT}" == "json" ]]; then
log INFO "β
VPC Endpoint Attachment Created"
else
# Display token information
log INFO "================================================"
log INFO "β
SUCCESS - VPC Endpoint Attachment Created"
log INFO "================================================"
log INFO "The Endpoint has been attached to your account in Databricks."
fi