From 452188180086c1154a524cad71c253a6bf821b0a Mon Sep 17 00:00:00 2001 From: Roman Loginov Date: Thu, 5 Dec 2024 16:08:55 +0300 Subject: [PATCH] [#529] Use salt when deriving the encryption key Salt is used when generating encryption keys for data (tokens) in the access box. Now frostfs-s3-authmate always derivation an encryption key with salt. Signed-off-by: Roman Loginov --- creds/accessbox/accessbox.go | 37 +++++++---- creds/accessbox/accessbox.pb.go | 56 ++++++++++------- creds/accessbox/accessbox.proto | 1 + creds/accessbox/accessbox_test.go | 49 ++++++++++++--- docs/authentication.md | 8 ++- .../authentication/accessbox-object.puml | 1 + .../authentication/accessbox-object.svg | 62 +------------------ 7 files changed, 107 insertions(+), 107 deletions(-) diff --git a/creds/accessbox/accessbox.go b/creds/accessbox/accessbox.go index 6d580f4..ca4fb7a 100644 --- a/creds/accessbox/accessbox.go +++ b/creds/accessbox/accessbox.go @@ -19,6 +19,11 @@ import ( "google.golang.org/protobuf/proto" ) +const ( + secretLength = 32 + saltLength = 16 +) + // Box represents friendly AccessBox. type Box struct { Gate *GateData @@ -109,7 +114,7 @@ func PackTokens(gatesData []*GateData, secret []byte, isCustomSecret bool) (*Acc box.IsCustom = isCustomSecret if secret == nil { - secret, err = generateSecret() + secret, err = generateRandomBytes(secretLength) if err != nil { return nil, nil, fmt.Errorf("failed to generate accessKey as hex: %w", err) } @@ -212,7 +217,12 @@ func encodeGate(ephemeralKey *keys.PrivateKey, seedKey *keys.PublicKey, tokens * return nil, fmt.Errorf("encode tokens: %w", err) } - encrypted, err := encrypt(ephemeralKey, seedKey, data) + salt, err := generateRandomBytes(saltLength) + if err != nil { + return nil, fmt.Errorf("failed to generate salt for encryption key: %w", err) + } + + encrypted, err := encrypt(ephemeralKey, seedKey, data, salt) if err != nil { return nil, fmt.Errorf("ecrypt tokens: %w", err) } @@ -220,11 +230,12 @@ func encodeGate(ephemeralKey *keys.PrivateKey, seedKey *keys.PublicKey, tokens * gate := new(AccessBox_Gate) gate.GatePublicKey = seedKey.Bytes() gate.Tokens = encrypted + gate.EncryptionKeySalt = salt return gate, nil } func (x *AccessBox) decodeGate(gate *AccessBox_Gate, owner *keys.PrivateKey, seedKey *keys.PublicKey) (*GateData, error) { - data, err := decrypt(owner, seedKey, gate.Tokens) + data, err := decrypt(owner, seedKey, gate.Tokens, gate.EncryptionKeySalt) if err != nil { return nil, fmt.Errorf("decrypt tokens: %w", err) } @@ -273,16 +284,16 @@ func generateShared256(prv *keys.PrivateKey, pub *keys.PublicKey) (sk []byte, er return sk, nil } -func deriveKey(secret []byte) ([]byte, error) { +func deriveKey(secret, salt []byte) ([]byte, error) { hash := sha256.New - kdf := hkdf.New(hash, secret, nil, nil) + kdf := hkdf.New(hash, secret, salt, nil) key := make([]byte, 32) _, err := io.ReadFull(kdf, key) return key, err } -func encrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]byte, error) { - enc, err := getCipher(owner, seedKey) +func encrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data, salt []byte) ([]byte, error) { + enc, err := getCipher(owner, seedKey, salt) if err != nil { return nil, fmt.Errorf("get chiper: %w", err) } @@ -295,8 +306,8 @@ func encrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]by return enc.Seal(nonce, nonce, data, nil), nil } -func decrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]byte, error) { - dec, err := getCipher(owner, seedKey) +func decrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data, salt []byte) ([]byte, error) { + dec, err := getCipher(owner, seedKey, salt) if err != nil { return nil, fmt.Errorf("get chiper: %w", err) } @@ -309,13 +320,13 @@ func decrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]by return dec.Open(nil, nonce, cypher, nil) } -func getCipher(owner *keys.PrivateKey, seedKey *keys.PublicKey) (cipher.AEAD, error) { +func getCipher(owner *keys.PrivateKey, seedKey *keys.PublicKey, salt []byte) (cipher.AEAD, error) { secret, err := generateShared256(owner, seedKey) if err != nil { return nil, fmt.Errorf("generate shared key: %w", err) } - key, err := deriveKey(secret) + key, err := deriveKey(secret, salt) if err != nil { return nil, fmt.Errorf("derive key: %w", err) } @@ -323,8 +334,8 @@ func getCipher(owner *keys.PrivateKey, seedKey *keys.PublicKey) (cipher.AEAD, er return chacha20poly1305.NewX(key) } -func generateSecret() ([]byte, error) { - b := make([]byte, 32) +func generateRandomBytes(length int) ([]byte, error) { + b := make([]byte, length) _, err := io.ReadFull(rand.Reader, b) return b, err } diff --git a/creds/accessbox/accessbox.pb.go b/creds/accessbox/accessbox.pb.go index dbe9517..0dc9be3 100644 --- a/creds/accessbox/accessbox.pb.go +++ b/creds/accessbox/accessbox.pb.go @@ -159,8 +159,9 @@ type AccessBox_Gate struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Tokens []byte `protobuf:"bytes,1,opt,name=tokens,proto3" json:"tokens,omitempty"` - GatePublicKey []byte `protobuf:"bytes,2,opt,name=gatePublicKey,proto3" json:"gatePublicKey,omitempty"` + Tokens []byte `protobuf:"bytes,1,opt,name=tokens,proto3" json:"tokens,omitempty"` + GatePublicKey []byte `protobuf:"bytes,2,opt,name=gatePublicKey,proto3" json:"gatePublicKey,omitempty"` + EncryptionKeySalt []byte `protobuf:"bytes,3,opt,name=encryptionKeySalt,proto3" json:"encryptionKeySalt,omitempty"` } func (x *AccessBox_Gate) Reset() { @@ -209,6 +210,13 @@ func (x *AccessBox_Gate) GetGatePublicKey() []byte { return nil } +func (x *AccessBox_Gate) GetEncryptionKeySalt() []byte { + if x != nil { + return x.EncryptionKeySalt + } + return nil +} + type AccessBox_ContainerPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -269,7 +277,7 @@ var File_creds_accessbox_accessbox_proto protoreflect.FileDescriptor var file_creds_accessbox_accessbox_proto_rawDesc = []byte{ 0x0a, 0x1f, 0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x22, 0xe3, 0x02, 0x0a, + 0x6f, 0x12, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x22, 0x91, 0x03, 0x0a, 0x09, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6f, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x67, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, @@ -282,29 +290,31 @@ var file_creds_accessbox_accessbox_proto_rawDesc = []byte{ 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, - 0x6d, 0x1a, 0x44, 0x0a, 0x04, 0x47, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x6b, + 0x6d, 0x1a, 0x72, 0x0a, 0x04, 0x47, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x1a, 0x59, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x22, 0x6e, 0x0a, 0x06, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x65, - 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x0a, 0x0d, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, - 0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, - 0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x73, 0x33, 0x2d, 0x67, - 0x77, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x62, 0x6f, 0x78, - 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x53, 0x61, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, + 0x79, 0x53, 0x61, 0x6c, 0x74, 0x1a, 0x59, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x22, 0x6e, 0x0a, 0x06, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x65, 0x61, 0x72, + 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, + 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e, + 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61, + 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x73, 0x33, 0x2d, 0x67, 0x77, 0x2f, + 0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x62, 0x6f, 0x78, 0x3b, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/creds/accessbox/accessbox.proto b/creds/accessbox/accessbox.proto index 2b0b1db..ab7c68e 100644 --- a/creds/accessbox/accessbox.proto +++ b/creds/accessbox/accessbox.proto @@ -10,6 +10,7 @@ message AccessBox { message Gate { bytes tokens = 1 [json_name = "tokens"]; bytes gatePublicKey = 2 [json_name = "gatePublicKey"]; + bytes encryptionKeySalt = 3 [json_name = "encryptionKeySalt"]; } message ContainerPolicy { diff --git a/creds/accessbox/accessbox_test.go b/creds/accessbox/accessbox_test.go index 5cd1693..e776f7d 100644 --- a/creds/accessbox/accessbox_test.go +++ b/creds/accessbox/accessbox_test.go @@ -23,6 +23,10 @@ func TestTokensEncryptDecrypt(t *testing.T) { tkn bearer.Token tkn2 bearer.Token ) + + salt, err := generateRandomBytes(saltLength) + require.NoError(t, err) + sec, err := keys.NewPrivateKey() require.NoError(t, err) @@ -32,16 +36,47 @@ func TestTokensEncryptDecrypt(t *testing.T) { tkn.SetEACLTable(*eacl.NewTable()) require.NoError(t, tkn.Sign(sec.PrivateKey)) - data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal()) - require.NoError(t, err) + t.Run("positive case without salt", func(t *testing.T) { + data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), nil) + require.NoError(t, err) - rawTkn2, err := decrypt(cred, cred.PublicKey(), data) - require.NoError(t, err) + rawTkn2, err := decrypt(cred, cred.PublicKey(), data, nil) + require.NoError(t, err) - err = tkn2.Unmarshal(rawTkn2) - require.NoError(t, err) + err = tkn2.Unmarshal(rawTkn2) + require.NoError(t, err) - assertBearerToken(t, tkn, tkn2) + assertBearerToken(t, tkn, tkn2) + }) + + t.Run("positive case with salt", func(t *testing.T) { + data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), salt) + require.NoError(t, err) + + rawTkn2, err := decrypt(cred, cred.PublicKey(), data, salt) + require.NoError(t, err) + + err = tkn2.Unmarshal(rawTkn2) + require.NoError(t, err) + + assertBearerToken(t, tkn, tkn2) + }) + + t.Run("wrong salt", func(t *testing.T) { + data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), salt) + require.NoError(t, err) + + _, err = decrypt(cred, cred.PublicKey(), data, nil) + require.Error(t, err) + }) + + t.Run("wrong private key", func(t *testing.T) { + data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), nil) + require.NoError(t, err) + + _, err = decrypt(sec, cred.PublicKey(), data, nil) + require.Error(t, err) + }) } func TestBearerTokenInAccessBox(t *testing.T) { diff --git a/docs/authentication.md b/docs/authentication.md index caac951..1f16221 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -199,6 +199,7 @@ It contains: in [spec](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/acl/types.proto#L189) * Marshaled session token - more detail in [spec](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/session/types.proto#L89) + * Encryption Key Salt - randomly generated 16 bytes that are used to derivation the encryption key * Container placement policies: * `LocationsConstraint` - name of location constraint that can be used to create bucket/container using s3 credentials related to this `AccessBox` @@ -258,19 +259,20 @@ secp256r1 or prime256v1) is used (unless otherwise stated). * Create ephemeral key (`SeedKey`), it's need to generate shared secret * Generate random 32-byte (that after hex-encoded be `SecretAccessKey`) or use existing secret access key (if `AccessBox` is being updated rather than creating brand new) or use arbitrary user-provided string +* Generate random 16-byte salt * Generate shared secret as [ECDH](https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman) -* Derive 32-byte key using shared secret from previous step with key derivation function based on +* Derive 32-byte key using shared secret from previous step and the salt with key derivation function based on HMAC with SHA256 [HKDF](https://en.wikipedia.org/wiki/HKDF) * Encrypt marshaled [Tokens](../creds/accessbox) using derived key with [ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) algorithm without additional data. **Decryption:** -* Get public part of `SeedKey` from `AccessBox` +* Get public part of `SeedKey` and the salt from `AccessBox` * Generate shared secret as follows: * Make scalar curve multiplication of public part of `SeedKey` and private part of s3-gw key * Use `X` part of multiplication (with zero padding at the beginning to fit 32-byte) -* Derive 32-byte key using shared secret from previous step with key derivation function based on +* Derive 32-byte key using shared secret from previous step and the salt with key derivation function based on HMAC with SHA256 [HKDF](https://en.wikipedia.org/wiki/HKDF) * Decrypt encrypted marshaled [Tokens](../creds/accessbox) using derived key with [ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) algorithm without additional data. diff --git a/docs/images/authentication/accessbox-object.puml b/docs/images/authentication/accessbox-object.puml index 28b9f24..37df3b1 100644 --- a/docs/images/authentication/accessbox-object.puml +++ b/docs/images/authentication/accessbox-object.puml @@ -10,6 +10,7 @@ package AccessBox { map Gate { GateKey => Encoded public gate key Encrypted tokens *--> Tokens + EncryptionKeySalt => Salt for derivation the encryption key } map ContainerPolicy { diff --git a/docs/images/authentication/accessbox-object.svg b/docs/images/authentication/accessbox-object.svg index 957efb7..a31b4d3 100644 --- a/docs/images/authentication/accessbox-object.svg +++ b/docs/images/authentication/accessbox-object.svg @@ -1,61 +1 @@ -AccessBoxTokensSecretKeyPrivate keyBearerTokenEncoded bearer tokenSessionTokensList of encoded session tokensGateGateKeyEncoded public gate keyEncrypted tokensContainerPolicyLocationConstraintPolicy namePlacementPolicyEncoded placement policyBoxSeedKeyEncoded public seed keyList of GatesList of container policiesIsCustomTrue if SecretKey was imported and must be treated as it isObjectAttributesTimestamp1710418478__SYSTEM__EXPIRATION_EPOCH10801S3-CRDT-Versions-Add5ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3Snxf,9bLtL1EsUpuSiqmHnqFf6RuT6x5QMLMNBqx7vCcCcNhyS3-Access-Box-CRDT-Name2XGRML5EW3LMHdf64W2DkBy1Nkuu4y4wGhUj44QjbXBi05ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3SnxfFilePath1710418478_access.boxFrostFSObjectHeaderPayload \ No newline at end of file +AccessBoxTokensSecretKeyPrivate keyBearerTokenEncoded bearer tokenSessionTokensList of encoded session tokensGateGateKeyEncoded public gate keyEncrypted tokensEncryptionKeySaltSalt for derivation the encryption keyContainerPolicyLocationConstraintPolicy namePlacementPolicyEncoded placement policyBoxSeedKeyEncoded public seed keyList of GatesList of container policiesIsCustomTrue if SecretKey was imported and must be treated as it isObjectAttributesTimestamp1710418478__SYSTEM__EXPIRATION_EPOCH10801S3-CRDT-Versions-Add5ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3Snxf,9bLtL1EsUpuSiqmHnqFf6RuT6x5QMLMNBqx7vCcCcNhyS3-Access-Box-CRDT-Name2XGRML5EW3LMHdf64W2DkBy1Nkuu4y4wGhUj44QjbXBi05ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3SnxfFilePath1710418478_access.boxFrostFSObjectHeaderPayload \ No newline at end of file