Skip to content

Commit 5be6d12

Browse files
committed
WIP
1 parent a3e871b commit 5be6d12

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

example/sm/main.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"time"
8+
9+
"github.com/aws/aws-sdk-go-v2/config"
10+
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
11+
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
12+
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
13+
"github.com/aws/aws-sdk-go/aws"
14+
"github.com/cloudopsy/dynamodb-encryption-go/pkg/encrypted"
15+
"github.com/cloudopsy/dynamodb-encryption-go/pkg/provider"
16+
"github.com/cloudopsy/dynamodb-encryption-go/pkg/provider/store"
17+
)
18+
19+
// Secret represents the structure of a secret stored in DynamoDB
20+
type Secret struct {
21+
TenantID string `dynamodbav:"TenantID"`
22+
NameVersion string `dynamodbav:"NameVersion"`
23+
Data []byte `dynamodbav:"Data"`
24+
Metadata map[string]string `dynamodbav:"Metadata"`
25+
CreatedAt int64 `dynamodbav:"CreatedAt"`
26+
UpdatedAt int64 `dynamodbav:"UpdatedAt"`
27+
Enabled bool `dynamodbav:"Enabled"`
28+
ExpiresAt int64 `dynamodbav:"ExpiresAt"`
29+
}
30+
31+
// SecretManager manages operations on secrets
32+
type SecretManager struct {
33+
encryptedTable *encrypted.EncryptedTable
34+
}
35+
36+
// NewSecretManager creates a new instance of SecretManager
37+
func NewSecretManager(et *encrypted.EncryptedTable) *SecretManager {
38+
return &SecretManager{
39+
encryptedTable: et,
40+
}
41+
}
42+
43+
// incrementVersion is a helper function to determine the next version number for a secret
44+
func (sm *SecretManager) incrementVersion(tenantID, secretID string) (int, error) {
45+
return 1, nil
46+
}
47+
48+
// WriteSecret writes a new version of a secret to the database
49+
func (sm *SecretManager) WriteSecret(ctx context.Context, tenantID, secretID string, plaintext []byte, metadata map[string]string) error {
50+
version, err := sm.incrementVersion(tenantID, secretID)
51+
if err != nil {
52+
return err
53+
}
54+
55+
// Create a new secret
56+
secret := Secret{
57+
TenantID: tenantID,
58+
NameVersion: fmt.Sprintf("%s#%d", secretID, version),
59+
Data: plaintext,
60+
Metadata: metadata,
61+
CreatedAt: time.Now().Unix(),
62+
UpdatedAt: time.Now().Unix(),
63+
Enabled: true,
64+
ExpiresAt: time.Now().Add(365 * 24 * time.Hour).Unix(), // Example: Expires in 1 year
65+
}
66+
67+
// Convert Secret struct to map[string]types.AttributeValue for DynamoDB
68+
item, err := attributevalue.MarshalMap(secret)
69+
if err != nil {
70+
log.Fatalf("Failed to marshal secret: %v", err)
71+
}
72+
73+
// Write the secret to the database using EncryptedTable
74+
return sm.encryptedTable.PutItem(ctx, "UserSecretsTest", item)
75+
}
76+
77+
func main() {
78+
// Setup and initialization code as previously shown
79+
ctx := context.TODO()
80+
cfg, err := config.LoadDefaultConfig(ctx)
81+
if err != nil {
82+
log.Fatalf("unable to load SDK config, %v", err)
83+
}
84+
85+
keyURI := "aws-kms://arn:aws:kms:eu-west-2:076594877490:key/02813db0-b23a-420c-94b0-bdceb08e121b"
86+
87+
// Create DynamoDB client
88+
dynamoDBClient := dynamodb.NewFromConfig(cfg)
89+
90+
// Initialize the key material store
91+
materialStore, err := store.NewMetaStore(dynamoDBClient, "meta")
92+
if err != nil {
93+
log.Fatalf("Failed to create key material store: %v", err)
94+
}
95+
96+
// Ensure DynamoDB table exists
97+
if err := materialStore.CreateTableIfNotExists(ctx); err != nil {
98+
log.Fatalf("Failed to ensure DynamoDB table exists: %v", err)
99+
}
100+
101+
// Initialize the cryptographic materials provider
102+
cmp, err := provider.NewAwsKmsCryptographicMaterialsProvider(keyURI, nil, materialStore)
103+
if err != nil {
104+
log.Fatalf("Failed to create cryptographic materials provider: %v", err)
105+
}
106+
107+
clientConfig := encrypted.NewClientConfig(
108+
encrypted.WithDefaultEncryption(encrypted.EncryptStandard),
109+
)
110+
111+
// Initialize EncryptedClient
112+
ec := encrypted.NewEncryptedClient(dynamoDBClient, cmp, clientConfig)
113+
114+
// Initialize EncryptedTable and SecretManager
115+
et := encrypted.NewEncryptedTable(ec)
116+
117+
// Define attribute definitions and key schema for the UserSecretsTest table
118+
attributeDefinitions := []types.AttributeDefinition{
119+
{
120+
AttributeName: aws.String("TenantID"),
121+
AttributeType: types.ScalarAttributeTypeS,
122+
},
123+
{
124+
AttributeName: aws.String("NameVersion"),
125+
AttributeType: types.ScalarAttributeTypeS,
126+
},
127+
// Add any other attributes used as keys in global/local secondary indexes
128+
}
129+
keySchema := []types.KeySchemaElement{
130+
{
131+
AttributeName: aws.String("TenantID"),
132+
KeyType: types.KeyTypeHash,
133+
},
134+
{
135+
AttributeName: aws.String("NameVersion"),
136+
KeyType: types.KeyTypeRange,
137+
},
138+
}
139+
140+
sm := NewSecretManager(et)
141+
142+
// Attempt to create the UserSecretsTest table
143+
_ = sm.encryptedTable.CreateTable(context.TODO(), "UserSecretsTest", attributeDefinitions, keySchema)
144+
145+
// Example usage of WriteSecret
146+
err = sm.WriteSecret(context.TODO(), "tenant1", "secretID1", []byte("mySecretData"), map[string]string{
147+
"Description": "Example secret",
148+
})
149+
if err != nil {
150+
log.Fatalf("Failed to write secret: %v", err)
151+
}
152+
fmt.Println("Secret written successfully.")
153+
}

example/sm/sm

24.8 MB
Binary file not shown.

0 commit comments

Comments
 (0)