authenticate k8 operator via token

This commit is contained in:
Maidul Islam
2022-12-15 16:36:33 -05:00
parent 595dc78e75
commit 805f733499
5 changed files with 192 additions and 1 deletions
+108
View File
@@ -0,0 +1,108 @@
package api
import (
"encoding/base64"
"errors"
"fmt"
"strings"
"github.com/Infisical/infisical/k8-operator/packages/crypto"
"github.com/Infisical/infisical/k8-operator/packages/models"
"github.com/go-resty/resty/v2"
"golang.org/x/crypto/nacl/box"
)
const INFISICAL_URL = "https://app.infisical.com/api"
func GetAllEnvironmentVariables(projectId string, envName string, infisicalToken string) ([]models.SingleEnvironmentVariable, error) {
envsFromApi, err := GetSecretsFromAPIUsingInfisicalToken(infisicalToken, envName, projectId)
if err != nil {
return nil, err
}
return envsFromApi, nil
}
func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string, projectId string) ([]models.SingleEnvironmentVariable, error) {
if infisicalToken == "" || projectId == "" || envName == "" {
return nil, errors.New("infisical token, project id and or environment name cannot be empty")
}
splitToken := strings.Split(infisicalToken, ",")
JTWToken := splitToken[0]
temPrivateKey := splitToken[1]
// create http client
httpClient := resty.New().
SetAuthToken(JTWToken).
SetHeader("Accept", "application/json")
var pullSecretsByInfisicalTokenResponse models.PullSecretsByInfisicalTokenResponse
response, err := httpClient.
R().
SetQueryParam("environment", envName).
SetQueryParam("channel", "cli").
SetResult(&pullSecretsByInfisicalTokenResponse).
Get(fmt.Sprintf("%v/v1/secret/%v/service-token", INFISICAL_URL, projectId))
if err != nil {
return nil, err
}
if response.StatusCode() > 299 {
return nil, fmt.Errorf(response.Status())
}
// Get workspace key
workspaceKey, err := base64.StdEncoding.DecodeString(pullSecretsByInfisicalTokenResponse.Key.EncryptedKey)
if err != nil {
return nil, err
}
nonce, err := base64.StdEncoding.DecodeString(pullSecretsByInfisicalTokenResponse.Key.Nonce)
if err != nil {
return nil, err
}
senderPublicKey, err := base64.StdEncoding.DecodeString(pullSecretsByInfisicalTokenResponse.Key.Sender.PublicKey)
if err != nil {
return nil, err
}
currentUsersPrivateKey, err := base64.StdEncoding.DecodeString(temPrivateKey)
if err != nil {
return nil, err
}
workspaceKeyInBytes, _ := box.Open(nil, workspaceKey, (*[24]byte)(nonce), (*[32]byte)(senderPublicKey), (*[32]byte)(currentUsersPrivateKey))
var listOfEnv []models.SingleEnvironmentVariable
for _, secret := range pullSecretsByInfisicalTokenResponse.Secrets {
key_iv, _ := base64.StdEncoding.DecodeString(secret.SecretKey.Iv)
key_tag, _ := base64.StdEncoding.DecodeString(secret.SecretKey.Tag)
key_ciphertext, _ := base64.StdEncoding.DecodeString(secret.SecretKey.Ciphertext)
plainTextKey, err := crypto.DecryptSymmetric(workspaceKeyInBytes, key_ciphertext, key_tag, key_iv)
if err != nil {
return nil, err
}
value_iv, _ := base64.StdEncoding.DecodeString(secret.SecretValue.Iv)
value_tag, _ := base64.StdEncoding.DecodeString(secret.SecretValue.Tag)
value_ciphertext, _ := base64.StdEncoding.DecodeString(secret.SecretValue.Ciphertext)
plainTextValue, err := crypto.DecryptSymmetric(workspaceKeyInBytes, value_ciphertext, value_tag, value_iv)
if err != nil {
return nil, err
}
env := models.SingleEnvironmentVariable{
Key: string(plainTextKey),
Value: string(plainTextValue),
}
listOfEnv = append(listOfEnv, env)
}
return listOfEnv, nil
}
+28
View File
@@ -0,0 +1,28 @@
package crypto
import (
"crypto/aes"
"crypto/cipher"
)
func DecryptSymmetric(key []byte, encryptedPrivateKey []byte, tag []byte, IV []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCMWithNonceSize(block, len(IV))
if err != nil {
return nil, err
}
var nonce = IV
var ciphertext = append(encryptedPrivateKey, tag...)
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return nil, err
}
return plaintext, nil
}
+51
View File
@@ -0,0 +1,51 @@
package models
import "time"
type PullSecretsByInfisicalTokenResponse struct {
Secrets []struct {
ID string `json:"_id"`
Workspace string `json:"workspace"`
Type string `json:"type"`
Environment string `json:"environment"`
SecretKey struct {
Workspace string `json:"workspace"`
Ciphertext string `json:"ciphertext"`
Iv string `json:"iv"`
Tag string `json:"tag"`
Hash string `json:"hash"`
} `json:"secretKey"`
SecretValue struct {
Workspace string `json:"workspace"`
Ciphertext string `json:"ciphertext"`
Iv string `json:"iv"`
Tag string `json:"tag"`
Hash string `json:"hash"`
} `json:"secretValue"`
} `json:"secrets"`
Key struct {
EncryptedKey string `json:"encryptedKey"`
Nonce string `json:"nonce"`
Sender struct {
PublicKey string `json:"publicKey"`
} `json:"sender"`
Receiver struct {
RefreshVersion int `json:"refreshVersion"`
ID string `json:"_id"`
Email string `json:"email"`
CustomerID string `json:"customerId"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
V int `json:"__v"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
PublicKey string `json:"publicKey"`
} `json:"receiver"`
Workspace string `json:"workspace"`
} `json:"key"`
}
type SingleEnvironmentVariable struct {
Key string `json:"key"`
Value string `json:"value"`
}