SDK
SDK Go
Client Go 1.21 et suivants. Chiffrement local, gestion des clés, journal d’audit, et le seul des trois SDK qui garantit l’effacement de la clé de données.
Installation
go get github.com/AxiomMarketing/mafate-goConstruction du client
import (
"os"
"time"
mafate "github.com/AxiomMarketing/mafate-go"
)
// ⛔ Le constructeur est New(apiKey, opts...).
// Il n'existe ni NewClient, ni type mafate.Config.
client := mafate.New(os.Getenv("MAFATE_API_KEY"))
// Avec options
client := mafate.New(
os.Getenv("MAFATE_API_KEY"),
mafate.WithBaseURL("https://api.mafate.io"),
mafate.WithTimeout(30*time.Second),
)Chiffrer et déchiffrer
keyID := os.Getenv("MAFATE_KEY_ID") // UUID rendu par POST /v1/keys
// Mode enveloppe : le clair ne quitte jamais ce processus.
env, err := client.EncryptLocal(ctx, []byte("donnee sensible"), keyID)
// env : *mafate.EnvelopeData
// Ciphertext, WrappedKey, IV, KeyID, KeyVersion, EnvelopeVersion
// ⚠️ DEUX VARIANTES AU DECHIFFREMENT, ET LE NOM COURT REND UNE CHAINE.
clair, err := client.DecryptLocal(ctx, env) // string
octets, err := client.DecryptLocalBytes(ctx, env) // []byte, pour du binaire
// Mode serveur, refuse par defaut depuis le 11/08/2026 (403) :
scelle, err := client.Encrypt(ctx, "donnee sensible", keyID)
clair, err = client.Decrypt(ctx, scelle)
brut, err := client.DecryptBytes(ctx, scelle)
// Empreinte deterministe. ⚠️ Seul appel qui transmet du clair a MAFATE,
// meme en mode enveloppe.
empreinte, err := client.Hash(ctx, strings.ToLower(email), keyID)Le type EnvelopeData
type EnvelopeData struct {
Ciphertext string `json:"ciphertext"` // base64, tag GCM concatene
WrappedKey string `json:"wrapped_key"` // jeton OPAQUE
IV string `json:"iv"` // base64, 12 octets
KeyID string `json:"key_id"`
KeyVersion int `json:"key_version"`
EnvelopeVersion int `json:"envelope_version"`
}
// ⛔ Les six champs se serialisent et se stockent ENSEMBLE. Un message gRPC,
// un evenement Kafka ou une colonne qui n'en relaie que trois produit des
// donnees definitivement illisibles, et l'ecriture reussit.
//
// ⛔ Le type mafate.Ciphertext n'existe pas : trois guides l'employaient.Services
// Cles de chiffrement
cles, err := client.Keys.List(ctx) // []Key
cle, err := client.Keys.Create(ctx, mafate.CreateKeyRequest{
Name: "production-users-pii",
})
detail, err := client.Keys.Get(ctx, cle.ID) // *KeyDetail, avec Versions
cle, err = client.Keys.Rotate(ctx, cle.ID)
err = client.Keys.SetRotationPolicy(ctx, cle.ID, &jours) // nil pour desactiver
err = client.Keys.Disable(ctx, cle.ID) // DELETE, irreversible
export, err := client.Keys.Export(ctx, cle.ID) // permission keys:export
// Cles d'API
apiKeys, err := client.ApiKeys.List(ctx)
neuve, err := client.ApiKeys.Create(ctx, mafate.CreateApiKeyRequest{
Name: "service-inscription",
Permissions: []string{"keys:wrap"},
})
err = client.ApiKeys.Revoke(ctx, neuve.ID)
// Journal d'audit
page, err := client.Audit.List(ctx, &mafate.AuditFilters{
Action: "key.unwrap",
Limit: 100,
})
verif, err := client.Audit.VerifyChain(ctx)Erreurs
env, err := client.EncryptLocal(ctx, clair, keyID)
if err != nil {
// ⛔ Le type est *mafate.ApiError, avec un champ Status.
// Il n'existe ni *mafate.APIError ni champ StatusCode : deux guides
// les employaient, et le errors.As ne matchait donc jamais.
var apiErr *mafate.ApiError
if errors.As(err, &apiErr) {
switch {
case apiErr.Status == 403:
// Permission manquante, ou locataire en mode enveloppe si vous
// avez appele Encrypt plutot qu'EncryptLocal.
return fmt.Errorf("refus definitif : %s", apiErr.Detail)
case apiErr.Status >= 500:
// Reessayer avec temporisation a du sens.
}
return err
}
var timeout *mafate.TimeoutError
var conn *mafate.ConnectionError
if errors.As(err, &timeout) || errors.As(err, &conn) {
// Le serveur n'a rien repondu : ni statut ni corps a interpreter.
}
return err
}L’effacement de la clé de données
EncryptLocal et DecryptLocal remettent la clé de données à zéro dès qu’elles en ont fini, y compris quand l’appel réseau échoue au milieu. En Go cette remise à zéro est effective : rien n’a recopié le tampon ailleurs. C’est la seule différence de fond entre les trois SDK, et elle mérite d’être citée telle quelle dans une analyse de risque, sans être étendue aux deux autres.