[#432] doc: Fix grammar mistakes in authentication
All checks were successful
/ DCO (pull_request) Successful in 1m57s
/ Builds (1.20) (pull_request) Successful in 2m53s
/ Builds (1.21) (pull_request) Successful in 2m38s
/ Vulncheck (pull_request) Successful in 2m42s
/ Lint (pull_request) Successful in 4m40s
/ Tests (1.20) (pull_request) Successful in 3m1s
/ Tests (1.21) (pull_request) Successful in 2m52s

Signed-off-by: Ekaterina Lebedeva <ekaterina.lebedeva@yadro.com>
This commit is contained in:
Ekaterina Lebedeva 2024-07-17 16:52:49 +03:00
parent 3b83de31d2
commit 1d965b23ab

View file

@ -6,23 +6,23 @@ This document describes s3-gw authentication and authorization mechanism.
Basic provisions: Basic provisions:
* A request to s3-gw can be signed or not (request that isn't signed we will cal anonymous or just anon) * A request to s3-gw can be signed or not (request that isn't signed we will call anonymous or just anon)
* To manage resources (buckets/objects) using s3-gw you must have appropriate access rights * To manage resources (buckets/objects) using s3-gw you must have appropriate access rights
Each request must be authenticated (at least as anonymous) and authorized. The following scheme shows components that Each request must be authenticated (at least as anonymous) and authorized. The following scheme shows components that
are involved to this are involved in this
process. process.
<a> <a>
<img src="images/authentication/auth-overview.svg" alt="Auth general overview"/> <img src="images/authentication/auth-overview.svg" alt="Auth general overview"/>
</a> </a>
There are several participants of this process: There are several participants in this process:
1. User that make a request 1. User that make a request
2. S3-GW that accepts a request 2. S3-GW that accepts a request
3. FrostFS Storage that stores AccessObjects (objects are needed for authentication) 3. FrostFS Storage that stores AccessObjects (objects are needed for authentication)
4. Blockchain smart contracts (`frostfsid`, `policy`) that stores user info and access rules. 4. Blockchain smart contracts (`frostfsid`, `policy`) that store user info and access rules.
## Data auth process ## Data auth process
@ -32,23 +32,23 @@ Let's look at the process in more detail:
<img src="images/authentication/auth-sequence.svg" alt="Auth sequence diagram"/> <img src="images/authentication/auth-sequence.svg" alt="Auth sequence diagram"/>
</a> </a>
* First of all, someone make a request. If request is signed we will check its signature (`Authentication`) after that * First of all, someone makes a request. If request is signed we will check its signature (`Authentication`) after that
we will check access rights using policies (`Auhorization`). For anonymous requests only authorization be performed. we will check access rights using policies (`Auhorization`). For anonymous requests only authorization is performed.
* **Authentication steps**: * **Authentication steps**:
* Each signed request is provided with `AccessKeyId` and signature. So if request is signed we must check its * Each signed request is provided with `AccessKeyId` and signature. So if request is signed we must check its
signature. To do this we must know the `AccessKeyId`/`SecretAccessKey` pair (How the signature is calculated signature. To do this we must know the `AccessKeyId`/`SecretAccessKey` pair (For how the signature is calculated
using this pair see [signing](#aws-signing). Client and server (s3-gw) use the same credentials and algorithm to using this pair, see [signing](#aws-signing). Client and server (s3-gw) use the same credentials and algorithm to
compute signature). The `AccessKeyId` is a public part of credentials, and it's passed to gate in request. The compute signature). The `AccessKeyId` is a public part of credentials, and it's passed to the gate in request. The
private part of credentials is `SecretAccessKey` and it's encrypted and stored in [AccessBox](#accessbox). So on private part of credentials is `SecretAccessKey` and it's encrypted and stored in [AccessBox](#accessbox). So on
this step we must find appropriate `AccessBox` in FrostFS storage node (How to find appropriate `AccessBox` this step we must find appropriate `AccessBox` in FrostFS storage node (For how to find appropriate `AccessBox`
knowing `AccessKeyId` see [search algorithm](#search-algorithm)). On this stage we can get `AccessDenied` from knowing `AccessKeyId`, see [search algorithm](#search-algorithm)). On this stage we can get `AccessDenied` from
FrostFS storage node if the s3-gw doesn't have permission to read this `AccessBox` object. FrostFS storage node if the s3-gw doesn't have permission to read this `AccessBox` object.
* After successful retrieving object we must extract `SecretAccessKey` from it. Since it's encrypted the s3-gw must * After successfully retrieving the object we must extract `SecretAccessKey` from it. Since it's encrypted, the s3-gw must
decrypt (see [encryption](#encryption)) this object using own private key and `SeedKey` from `AccessBox` decrypt (see [encryption](#encryption)) this object using its own private key and `SeedKey` from `AccessBox`
(see [AccessBox inner structure](#accessbox)). After s3-gw have got the `AccessKeyId`/`SecretAccessKey` pair it (see [AccessBox inner structure](#accessbox)). After s3-gw got the `AccessKeyId`/`SecretAccessKey` pair it
[calculate signature](#aws-signing) and compare got signature with provided withing request. If signature doesn't [calculates signature](#aws-signing) and compares this signature with one provided by the request. If signature doesn't
match the `AccessDenied` is returned. match the `AccessDenied` is returned.
* `AccessBox` also contains `OwnerID` that is related to `AccessKeyId` that was provided. So we have to check if * `AccessBox` also contains `OwnerID` that is related to `AccessKeyId` that was provided. So we have to check if
@ -63,7 +63,7 @@ Let's look at the process in more detail:
* After successful authentication and authorization the request will be processed by s3-gw business logic and finally be * After successful authentication and authorization the request will be processed by s3-gw business logic and finally be
propagated to FrostFS storage node which also performs some auth checks and can return `AccessDenied`. If this happens propagated to FrostFS storage node which also performs some auth checks and can return `AccessDenied`. If this happens
s3-gw also returns `AccessDenied` as response. s3-gw also returns `AccessDenied` as a response.
### AWS Signing ### AWS Signing
@ -77,7 +77,7 @@ authentication with the AWS Signature Version 4 algorithm. More info in AWS docu
You can express authentication information by using one of the following methods: You can express authentication information by using one of the following methods:
* **HTTP Authorization header** - Using the HTTP Authorization header is the most common method of authenticating an * **HTTP Authorization header** - Using the HTTP Authorization header is the most common method of authenticating
FrostFS S3 request. All the FrostFS S3 REST operations (except for browser-based uploads using POST requests) require FrostFS S3 request. All the FrostFS S3 REST operations (except for browser-based uploads using POST requests) require
this header. For more information about the Authorization header value, and how to calculate signature and related this header. For more information about the Authorization header value, and how to calculate signature and related
options, options,
@ -114,7 +114,7 @@ parameters for authentication, you use a varying combination of request elements
HTTP POST request, the POST policy in the request is the string you sign. For more information about computing string to HTTP POST request, the POST policy in the request is the string you sign. For more information about computing string to
sign, follow links provided at the end of this section. sign, follow links provided at the end of this section.
For signing key, the diagram shows series of calculations, where result of each step you feed into the next step. The For signing key, the diagram shows series of calculations, where the result of each step you feed into the next step. The
final step is the signing key. final step is the signing key.
Upon receiving an authenticated request, FrostFS S3 servers re-create the signature by using the authentication Upon receiving an authenticated request, FrostFS S3 servers re-create the signature by using the authentication
@ -139,7 +139,7 @@ See detains in [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/A
#### s3-gw #### s3-gw
s3-gw support the following ways to provide the singed request: s3-gw supports the following ways to provide the singed request:
* [HTTP Authorization header](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html) * [HTTP Authorization header](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html)
* [Query string parameters](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html) * [Query string parameters](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)
@ -153,10 +153,10 @@ if they don't match the access denied is returned.
### AccessBox ### AccessBox
`AccessBox` is an ordinary object in FrostFS storage. It contains all information that can be used by s3-gw to `AccessBox` is an ordinary object in FrostFS storage. It contains all information that can be used by s3-gw to
successfully authenticate request. Also, it contains data that is required to successful authentication in FrostFS successfully authenticate request. Also, it contains data that is required for successful authentication in FrostFS
storage node. storage node.
Based on this object s3 credentials are formed: Object s3 credentials are formed based on:
* `AccessKeyId` - is concatenated container id and object id (`<cid>0<oid>`) of `AccessBox` ( * `AccessKeyId` - is concatenated container id and object id (`<cid>0<oid>`) of `AccessBox` (
e.g. `2XGRML5EW3LMHdf64W2DkBy1Nkuu4y4wGhUj44QjbXBi05ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3Snxf`) e.g. `2XGRML5EW3LMHdf64W2DkBy1Nkuu4y4wGhUj44QjbXBi05ZNvs8WVwy1XTmSEkcVkydPKzCgtmR7U3zyLYTj3Snxf`)
@ -173,9 +173,9 @@ Based on this object s3 credentials are formed:
**Headers:** **Headers:**
`AccessBox` object has the following attributes (at least them, it also can contain custom one): `AccessBox` object has the following attributes (at least them, it also can contain custom ones):
* `Timestamp` - unix timestamp when object was created * `Timestamp` - unix timestamp indicating when the object was created
* `__SYSTEM__EXPIRATION_EPOCH` - epoch after which the object isn't available anymore * `__SYSTEM__EXPIRATION_EPOCH` - epoch after which the object isn't available anymore
* `S3-CRDT-Versions-Add` - comma separated list of previous versions of `AccessBox` ( * `S3-CRDT-Versions-Add` - comma separated list of previous versions of `AccessBox` (
see [AccessBox versions](#accessbox-versions)) see [AccessBox versions](#accessbox-versions))
@ -190,7 +190,7 @@ It contains:
* Seed key - hex-encoded public seed key to compute shared secret using ECDH (see [encryption](#encryption)) * Seed key - hex-encoded public seed key to compute shared secret using ECDH (see [encryption](#encryption))
* List of gate data: * List of gate data:
* Gate public key (so that gate (when it will decrypt data later) know which one item from list it should process) * Gate public key (so that gate (when it will decrypt data later) know which item from the list it should process)
* Encrypted tokens: * Encrypted tokens:
* `SecretAccessKey` - hex-encoded random generated 32 bytes * `SecretAccessKey` - hex-encoded random generated 32 bytes
* Marshaled bearer token - more detail * Marshaled bearer token - more detail
@ -207,16 +207,16 @@ It contains:
Imagine the following scenario: Imagine the following scenario:
* There is a system where only one s3-gw exist * There is a system where only one s3-gw exists
* There is a `AccessBox` that can be used by this s3-gw * There is an `AccessBox` that can be used by this s3-gw
* User has s3 credentials (`AccessKeyId`/`SecretAccessKey`) related to corresponded `AccessBox` and can successfully * User has s3 credentials (`AccessKeyId`/`SecretAccessKey`) related to corresponding `AccessBox` and can successfully
make request to s3-gw make request to s3-gw
* The system is expanded and new one s3-gw is added * The system is expanded and a new s3-gw is added
* User must be able to use the credentials (that he has already had) to make request to new one s3-gw * User must be able to use the credentials (that he has already had) to make request to the new s3-gw
Since `AccessBox` object is immutable and `SecretAccessKey` is encrypted only for restricted list of keys (can be used Since `AccessBox` object is immutable and `SecretAccessKey` is encrypted only for restricted list of keys (can be used
(decrypted) only by limited number of s3-gw) we have to create new `AccessBox` that has encrypted secrets for new list (decrypted) only by limited number of s3-gw) we have to create a new `AccessBox` that has encrypted secrets for a new list
of s3-gw and be related to initial s3 credentials (`AccessKeyId`/`SecretAccessKey`). Such relationship is done of s3-gw and is related to the initial s3 credentials (`AccessKeyId`/`SecretAccessKey`). Such relation is done
by `S3-Access-Box-CRDT-Name`. by `S3-Access-Box-CRDT-Name`.
##### Search algorithm ##### Search algorithm
@ -285,10 +285,10 @@ is performed the following algorithm is applied:
* If no rules were matched return `deny` status. * If no rules were matched return `deny` status.
To local and contract policies `deny first` scheme is applied. This means that if several rules were matched for To local and contract policies `deny first` scheme is applied. This means that if several rules were matched for
reqeust (with both statuses `allow` and `deny`) the resulting status be `deny`. reqeust (with both statuses `allow` and `deny`) the resulting status is `deny`.
Policy rules validate if specified request can be performed on the specific resource. Request and resource can contain Policy rules validate if specified request can be performed on the specific resource. Request and resource can contain
some properties and rules can contain conditions on some such properties. some properties, and rules can contain conditions on some of these properties.
In s3-gw resource is `/bucket/object`, `/bucket` or just `/` (if request is trying to list buckets). In s3-gw resource is `/bucket/object`, `/bucket` or just `/` (if request is trying to list buckets).
Currently, request that is checked contains the following properties (so policy rule can contain conditions on them): Currently, request that is checked contains the following properties (so policy rule can contain conditions on them):