SDK Usage in Code

Integrate tokenize and detokenize into your application.

What to change in your project

  1. Add VAULT_URL to your app config or secrets.
  2. Add an HTTP client with tokenize and detokenize methods.

Integration is HTTP + JSON only. You do not need to add the Securelytix repository as a Go module.

Where to use the Vault API

HTTP / API handlers

  • Incoming API calls (create / update / submit): tokenize in the request handler, then store tokens in your database.
  • Outgoing API responses: return stored tokens as-is; detokenize only for admin, support, or internal endpoints that need plaintext.
  • Downstream HTTP calls: tokenize JSON bodies before POSTing to microservices or webhooks.

Runtime tokenization — when to call

Call tokenize before INSERT/UPDATE, before enqueueing a job, before writing to a cache key that might be dumped, or before emitting to a bus.

Runtime detokenization — when to call

Call detokenize only in narrow flows: reporting export, fulfillment, billing reconciliation, or a screened internal UI. Avoid detokenizing on every read if the consumer only needs the tokenized view.

Storing tokens instead of raw values

After tokenization, the response has the same keys and nesting as your input; only classified PII fields become tokens. Persist that object — never store the pre-tokenize payload.

TypeScript / JavaScript client

javascript · terminal
1export function createVaultClient({ baseUrl, fetchImpl = fetch }) {
2 const root = baseUrl.replace(/\/$/, "");
3 return {
4 async tokenize(data, headers = {}) {
5 const r = await fetchImpl(`${root}/api/v1/tokenize`, {
6 method: "POST",
7 headers: {
8 "Content-Type": "application/json",
9 ...(headers.customerId ? { "X-Customer-ID": headers.customerId } : {}),
10 },
11 body: JSON.stringify({ data }),
12 });
13 if (!r.ok) throw new Error(`vault tokenize ${r.status}: ${await r.text()}`);
14 return r.json();
15 },
16 async detokenize(data) {
17 const r = await fetchImpl(`${root}/api/v1/detokenize`, {
18 method: "POST",
19 headers: { "Content-Type": "application/json" },
20 body: JSON.stringify({ data }),
21 });
22 if (!r.ok) throw new Error(`vault detokenize ${r.status}: ${await r.text()}`);
23 return r.json();
24 },
25 };
26}
27
28const vault = createVaultClient({ baseUrl: process.env.VAULT_URL });

Go client

go · terminal
1package vaultclient
2
3import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "fmt"
8 "net/http"
9 "strings"
10)
11
12type Client struct {
13 BaseURL string
14 HTTP *http.Client
15}
16
17func New(baseURL string) *Client {
18 return &Client{BaseURL: strings.TrimRight(baseURL, "/"), HTTP: http.DefaultClient}
19}
20
21func (c *Client) Tokenize(ctx context.Context, data map[string]any, customerID string) (map[string]any, error) {
22 body, _ := json.Marshal(map[string]any{"data": data})
23 req, _ := http.NewRequestWithContext(ctx, http.MethodPost, c.BaseURL+"/api/v1/tokenize", bytes.NewReader(body))
24 req.Header.Set("Content-Type", "application/json")
25 if customerID != "" {
26 req.Header.Set("X-Customer-ID", customerID)
27 }
28 resp, err := c.HTTP.Do(req)
29 if err != nil { return nil, err }
30 defer resp.Body.Close()
31 if resp.StatusCode < 200 || resp.StatusCode >= 300 {
32 return nil, fmt.Errorf("tokenize: status %d", resp.StatusCode)
33 }
34 var out struct{ Data map[string]any }
35 json.NewDecoder(resp.Body).Decode(&out)
36 return out.Data, nil
37}

Minimal code patterns

Ingest / create — tokenize, then persist

javascript · terminal
1const { data } = await vault.tokenize(payload, { customerId: tenantId });
2await saveToDatabase({ ...record, payload: data });

Privileged read — load, detokenize, return

javascript · terminal
1const row = await loadFromDatabase(id);
2const { data, status, failed_fields } = await vault.detokenize(row.payload);
3if (status === "partial_success" && failed_fields?.length) {
4 /* log metrics; some fields may remain token strings */
5}
6return data;

TypeScript / JavaScript — API route examples

Incoming POST /api/users — tokenize before persisting

javascript · terminal
1app.post("/api/users", async (req, res) => {
2 const body = req.body;
3 const { data: safe } = await vault.tokenize(body, {
4 customerId: req.header("x-tenant-id") ?? undefined,
5 });
6 await saveUser(safe);
7 res.status(201).json({ id: "..." });
8});

Outgoing GET /api/admin/users/:id — detokenize before response

javascript · terminal
1app.get("/api/admin/users/:id", requireAdmin, async (req, res) => {
2 const row = await loadUser(req.params.id);
3 const { data, status, failed_fields } = await vault.detokenize(row.profile);
4 if (status === "partial_success" && failed_fields?.length) {
5 req.log?.warn({ failed_fields }, "partial detokenize");
6 }
7 res.json({ ...row, profile: data });
8});

Go — API handler examples

go · terminal
1func (s *Server) createUser(w http.ResponseWriter, r *http.Request) {
2 var body map[string]any
3 json.NewDecoder(r.Body).Decode(&body)
4 safe, err := s.vault.Tokenize(r.Context(), body, r.Header.Get("X-Tenant-ID"))
5 if err != nil { http.Error(w, "tokenize", http.StatusBadGateway); return }
6 s.store.InsertUser(r.Context(), safe)
7 w.WriteHeader(http.StatusCreated)
8}

Was this page helpful?