Agent skill

cva-setup-vertex

Complete Vertex AI and Google Cloud Platform setup for Clojure agent development. Includes GCP project saas3-476116 credentials, security best practices (IAM, key rotation, LGPD), cost analysis, API enablement, and environment configuration. Use when starting new Clojure+Vertex project, configuring GCP credentials, implementing security compliance, or troubleshooting authentication.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/security/cva-setup-vertex

SKILL.md

Vertex AI Project Context - Clojure Integration Setup

Last Updated: 2025-10-27 Status: Python/ADK environment validated, ready for Clojure integration GCP Project: saas3-476116


๐ŸŽฏ Overview

This skill consolidates complete context for the existing Vertex AI project to facilitate integration with Clojure. The goal is to leverage the already-configured GCP infrastructure and lessons learned from Python ADK to create agents using Clojure.


๐Ÿ” Credentials and GCP Configuration

Google Cloud Project

Property Value
Project ID saas3-476116
Primary Region us-central1
Service Account vertex-ai-app@saas3-476116.iam.gserviceaccount.com
JSON Key ~/.gcp-credentials/vertex-ai-app-key.json
Key Permissions chmod 600 (always verify)

Enabled APIs

bash
# Critical APIs already enabled
- aiplatform.googleapis.com         # Vertex AI API
- generativelanguage.googleapis.com # Gemini API
- cloudbuild.googleapis.com         # Cloud Build
- run.googleapis.com                # Cloud Run

# Verify APIs
gcloud services list --enabled --project=saas3-476116

Essential Environment Variables

File: ~/.env (chmod 600, DO NOT commit)

bash
# Google Cloud Configuration
export GOOGLE_CLOUD_PROJECT="saas3-476116"
export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.gcp-credentials/vertex-ai-app-key.json"
export GOOGLE_CLOUD_LOCATION="us-central1"

# Vertex AI Endpoint
export VERTEX_AI_ENDPOINT="us-central1-aiplatform.googleapis.com"

# For Vertex AI with Google Generative AI SDK
export GOOGLE_GENAI_USE_VERTEXAI="TRUE"

# ADK Configuration
export ADK_MODEL="gemini-1.5-flash"
export ADK_TEMPERATURE="0.7"
export ADK_MAX_TOKENS="2048"

โš ๏ธ CRITICAL: Protect file:

bash
chmod 600 ~/.env

Clojure Configuration

Read environment variables in Clojure:

clojure
(ns lab.config.google-cloud
  "Google Cloud configuration from environment"
  (:require [clojure.java.io :as io]))

(defn get-env
  "Reads environment variable with fallback"
  [key default]
  (or (System/getenv key) default))

(def gcp-config
  {:project-id (get-env "GOOGLE_CLOUD_PROJECT" "saas3-476116")
   :location (get-env "GOOGLE_CLOUD_LOCATION" "us-central1")
   :credentials (get-env "GOOGLE_APPLICATION_CREDENTIALS"
                        (str (System/getProperty "user.home")
                             "/.gcp-credentials/vertex-ai-app-key.json"))
   :endpoint (get-env "VERTEX_AI_ENDPOINT"
                     "us-central1-aiplatform.googleapis.com")})

(defn validate-credentials
  "Validates that credentials file exists and is readable"
  []
  (let [creds-file (io/file (:credentials gcp-config))]
    (when-not (.exists creds-file)
      (throw (ex-info "Credentials file not found"
                      {:path (:credentials gcp-config)})))
    (when-not (.canRead creds-file)
      (throw (ex-info "Credentials file not readable"
                      {:path (:credentials gcp-config)})))
    true))

;; Usage
(comment
  (validate-credentials)
  ;; => true or throws ex-info

  (:project-id gcp-config)
  ;; => "saas3-476116"
  )

๐Ÿ“Š IAM and Security

Service Account Roles

Current Role: roles/aiplatform.user (least privilege)

bash
# Verify current roles
gcloud projects get-iam-policy saas3-476116 \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:vertex-ai-app*"

# Expected output:
# - roles/aiplatform.user (use Vertex AI)

Key Rotation (Mandatory every 90 days)

bash
# 1. List existing keys
gcloud iam service-accounts keys list \
  --iam-account=vertex-ai-app@saas3-476116.iam.gserviceaccount.com \
  --format="table(name,validAfterTime,validBeforeTime)"

# 2. Create new key
gcloud iam service-accounts keys create \
  ~/.gcp-credentials/vertex-ai-app-key-new.json \
  --iam-account=vertex-ai-app@saas3-476116.iam.gserviceaccount.com

# 3. Protect
chmod 600 ~/.gcp-credentials/vertex-ai-app-key-new.json

# 4. Test
GOOGLE_APPLICATION_CREDENTIALS=~/.gcp-credentials/vertex-ai-app-key-new.json \
  gcloud auth application-default print-access-token

# 5. Update ~/.env and delete old key
gcloud iam service-accounts keys delete OLD_KEY_ID \
  --iam-account=vertex-ai-app@saas3-476116.iam.gserviceaccount.com

Security Audit Checklist (Monthly)

  • Rotate keys (every 90 days)
  • Review IAM permissions
  • Verify enabled APIs (disable unused)
  • Analyze costs
  • Verify .gitignore (no keys committed)
  • Check service account activity logs
  • Review Vertex AI quotas

๐Ÿ’ฐ Observed Costs and Estimates

Real Costs (Healthcare Pipeline - 20 posts/month)

Component Cost per Execution Monthly (20 posts)
S.1.1 (Type B - LGPD Extraction) $0.045 $0.90
S.1.2 (Type A - Claims ID) $0.021 $0.42
S.2-1.2 (Type C - References) $0.067 $1.34
S.3-2 (Type B - SEO) $0.078 $1.56
S.4 (Type D - Consolidation) $0.18 $3.60
Total per post $0.391 $7.82

With optimizations (cache + parallel):

  • Cost per post: $0.162 (-58.6%)
  • Monthly: $3.24 (-58.6%)

Model Pricing (us-central1)

Model Input (1M tokens) Output (1M tokens) Best For
gemini-1.5-flash $0.075 $0.30 Type A/B (70% of tasks)
gemini-1.5-pro $1.25 $5.00 Type C/D (complex reasoning)
gemini-2.5-flash $0.10 $0.40 Balanced (future)

Multi-model strategy savings: 41% vs Claude-only


๐Ÿ› ๏ธ Clojure + Vertex AI Setup

deps.edn Configuration

clojure
{:paths ["src" "resources"]
 :deps {org.clojure/clojure {:mvn/version "1.11.1"}

        ;; Google Cloud Vertex AI (Java SDK)
        com.google.cloud/google-cloud-aiplatform {:mvn/version "3.36.0"}
        com.google.cloud/google-cloud-vertexai {:mvn/version "0.2.0"}

        ;; Google Auth
        com.google.auth/google-auth-library-oauth2-http {:mvn/version "1.19.0"}

        ;; JSON handling
        cheshire/cheshire {:mvn/version "5.11.0"}

        ;; HTTP client
        clj-http/clj-http {:mvn/version "3.12.3"}

        ;; Database (if using Type B/D)
        com.github.seancorfield/next.jdbc {:mvn/version "1.3.909"}
        org.postgresql/postgresql {:mvn/version "42.6.0"}

        ;; Python interop (optional, for libpython-clj)
        clj-python/libpython-clj {:mvn/version "2.025"}

        ;; Logging
        org.clojure/tools.logging {:mvn/version "1.2.4"}
        ch.qos.logback/logback-classic {:mvn/version "1.4.11"}}

 :aliases
 {:dev {:extra-paths ["dev"]
        :extra-deps {nrepl/nrepl {:mvn/version "1.0.0"}
                     cider/cider-nrepl {:mvn/version "0.30.0"}}}

  :test {:extra-paths ["test"]
         :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"}}}}}

Basic Vertex AI Agent (Type A)

clojure
(ns lab.agents.basic
  "Basic Type A agent example"
  (:require [lab.config.google-cloud :as gc]
            [cheshire.core :as json])
  (:import [com.google.cloud.vertexai VertexAI]
           [com.google.cloud.vertexai.generativeai GenerativeModel]
           [com.google.cloud.vertexai.api GenerationConfig]))

(defn create-vertex-ai-instance
  "Creates Vertex AI instance with credentials."
  []
  (let [{:keys [project-id location credentials]} gc/gcp-config]
    (gc/validate-credentials)
    (VertexAI. project-id location)))

(defn create-generative-model
  "Creates a generative model."
  ([vertex-ai] (create-generative-model vertex-ai "gemini-1.5-flash"))
  ([vertex-ai model-name]
   (let [generation-config (-> (GenerationConfig/newBuilder)
                               (.setTemperature 0.7)
                               (.setMaxOutputTokens 2048)
                               (.setTopP 0.95)
                               (.build))
         model (.getGenerativeModel vertex-ai model-name)]
     (.withGenerationConfig model generation-config))))

(defn generate-content
  "Generates content from prompt."
  [model prompt]
  (let [response (.generateContent model prompt)]
    {:text (-> response .getText)
     :metadata {:model (.getModelName model)
                :finish-reason (-> response .getCandidates first .getFinishReason str)}}))

;; REPL Usage
(comment
  ;; 1. Create Vertex AI instance
  (def vertex-ai (create-vertex-ai-instance))

  ;; 2. Create model
  (def model (create-generative-model vertex-ai "gemini-1.5-flash"))

  ;; 3. Generate content
  (def result
    (generate-content
      model
      "Explain functional programming in Clojure in 3 sentences."))

  (:text result)
  ;; => "Functional programming in Clojure emphasizes..."

  ;; 4. Clean up
  (.close vertex-ai)
  )

๐Ÿ”’ Security Best Practices

1. Credentials Management

DO:

  • โœ… Store credentials in ~/.gcp-credentials/ (outside repo)
  • โœ… Use chmod 600 on all credential files
  • โœ… Set GOOGLE_APPLICATION_CREDENTIALS environment variable
  • โœ… Rotate keys every 90 days
  • โœ… Use service accounts (not user accounts)

DON'T:

  • โŒ Commit credentials to git
  • โŒ Share credentials via chat/email
  • โŒ Use keys older than 90 days
  • โŒ Give excessive permissions (roles/owner)

2. .gitignore (Mandatory)

gitignore
# GCP Credentials
.gcp-credentials/
*-key.json
*.json.enc

# Environment files
.env
.env.local
.env.*.local

# Secrets
secrets/
credentials/

3. Least Privilege IAM

Minimum roles needed:

  • roles/aiplatform.user - Use Vertex AI
  • roles/logging.viewer - View logs (optional)

Avoid:

  • roles/owner - Too broad
  • roles/editor - Too broad
  • roles/aiplatform.admin - Unless deploying

4. LGPD Compliance (Brazil)

When processing personal data:

clojure
(ns lab.compliance.lgpd
  "LGPD compliance utilities")

(def sensitive-data-patterns
  "Patterns for detecting sensitive personal data"
  {:cpf #"\d{3}\.\d{3}\.\d{3}-\d{2}"
   :rg #"\d{1,2}\.\d{3}\.\d{3}-\d{1,2}"
   :email #"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
   :phone #"\(?[0-9]{2}\)?\s?[0-9]{4,5}-?[0-9]{4}"
   :health-data #"(?i)(diabetes|hipertens[รฃa]o|depress[รฃa]o|ansiedade)"})

(defn detect-sensitive-data
  "Detects sensitive personal data in text."
  [text]
  (reduce-kv
    (fn [acc data-type pattern]
      (if (re-find pattern text)
        (conj acc data-type)
        acc))
    []
    sensitive-data-patterns))

(defn sanitize-for-logging
  "Removes sensitive data before logging."
  [text]
  (reduce-kv
    (fn [sanitized data-type pattern]
      (clojure.string/replace sanitized pattern "[REDACTED]"))
    text
    sensitive-data-patterns))

;; Usage
(comment
  (detect-sensitive-data "Cliente: Joรฃo Silva, CPF: 123.456.789-00")
  ;; => [:cpf]

  (sanitize-for-logging "Cliente: Joรฃo Silva, CPF: 123.456.789-00")
  ;; => "Cliente: Joรฃo Silva, CPF: [REDACTED]"
  )

๐Ÿ“˜ Full compliance guide: See cva-healthcare-compliance skill.


๐Ÿงช Testing and Validation

Verify GCP Setup

bash
# 1. Verify gcloud auth
gcloud auth application-default print-access-token

# 2. Verify project
gcloud config get-value project
# Expected: saas3-476116

# 3. Verify APIs
gcloud services list --enabled --project=saas3-476116 | grep aiplatform

# 4. Test Vertex AI access
gcloud ai models list --region=us-central1 --project=saas3-476116

Clojure Integration Test

clojure
(ns lab.test.integration
  "Integration tests for Vertex AI"
  (:require [clojure.test :refer :all]
            [lab.config.google-cloud :as gc]
            [lab.agents.basic :as basic]))

(deftest test-vertex-ai-connection
  (testing "Can create Vertex AI instance"
    (let [vertex-ai (basic/create-vertex-ai-instance)]
      (is (some? vertex-ai))
      (.close vertex-ai))))

(deftest test-model-generation
  (testing "Can generate content"
    (let [vertex-ai (basic/create-vertex-ai-instance)
          model (basic/create-generative-model vertex-ai)
          result (basic/generate-content model "Say 'test'")]
      (is (string? (:text result)))
      (is (> (count (:text result)) 0))
      (.close vertex-ai))))

Run tests:

bash
clojure -X:test

๐Ÿšจ Troubleshooting

"Credentials not found"

Problem: GOOGLE_APPLICATION_CREDENTIALS not set or file doesn't exist

Solution:

bash
# Verify file exists
ls -la ~/.gcp-credentials/vertex-ai-app-key.json

# Verify permissions
chmod 600 ~/.gcp-credentials/vertex-ai-app-key.json

# Set environment variable
export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.gcp-credentials/vertex-ai-app-key.json"

# Test
gcloud auth application-default print-access-token

"API not enabled"

Problem: Vertex AI API not enabled for project

Solution:

bash
gcloud services enable aiplatform.googleapis.com --project=saas3-476116

"Permission denied"

Problem: Service account lacks necessary roles

Solution:

bash
gcloud projects add-iam-policy-binding saas3-476116 \
  --member="serviceAccount:vertex-ai-app@saas3-476116.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"

"Quota exceeded"

Problem: Exceeded Vertex AI quotas

Solution:

bash
# Check quotas
gcloud compute project-info describe --project=saas3-476116

# Request quota increase (if needed)
# https://console.cloud.google.com/iam-admin/quotas?project=saas3-476116

๐Ÿ”— Related Skills


๐Ÿ“˜ Additional Documentation


This setup is validated for production healthcare systems with proven ROI. Follow security best practices rigorously.

Didn't find tool you were looking for?

Be as detailed as possible for better results