Skip to content

Commit c8ee97b

Browse files
Simplify BYOS section
1 parent c737442 commit c8ee97b

File tree

1 file changed

+28
-43
lines changed

1 file changed

+28
-43
lines changed

azure/Guidelines.md

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -760,79 +760,64 @@ while the Microsoft guidelines use the name "Operation-Location".
760760

761761
:white_check_mark: **DO** look for **both** HEADERS in client code, preferring the `Operation-Location` version.
762762

763-
### Bring your own Storage
764-
When implementing your service, it is very common to store and retrieve data and files. When you encounter this scenario, avoid implementing your own storage strategy and instead use Azure Bring Your Own Storage (BYOS). BYOS provides significant benefits to service implementors, e.g. security, an aggressively optimized frontend, uptime, etc.
765-
While Azure Managed Storage may be easier to get started with, as your service evolves and matures, BYOS will provide the most flexibility and implementation choices. Further, when designing your APIs, be cognizant of expressing storage concepts and how clients will access your data. For example, if you are working with blobs, then you should not expose the concept of folders, nor do they have extensions.
763+
### Bring your own Storage (BYOS)
764+
Many services need to store and retrieve data files. For this scenario, teh service should not implement its own
765+
storage mechanism and should instead leverage the existing Azure Storage service. When doing this, the customer
766+
"owns" the storage account and just tells your service to use it. Colloquially, we call this <i>Bring Your Own Storage</i> as the customer is bringing their storage account to another service. BYOS provides significant benefits to service implementors: security, performance, uptime, etc. And, of course, most Azure customers are already with the Azure Storage service.
766767

767-
:white_check_mark: **DO** use Azure Bring Your Own Storage.
768+
While Azure Managed Storage may be easier to get started with, as your service evolves and matures, BYOS provides the most flexibility and implementation choices. Further, when designing your APIs, be cognizant of expressing storage concepts and how clients will access your data. For example, if you are working with blobs, then you should not expose the concept of folders.
768769

769-
:white_check_mark: **DO** use a blob prefix
770+
:white_check_mark: **DO** use the Bring Your Own Storage pattern
771+
772+
:white_check_mark: **DO** use a blob prefix for logical folders
770773

771774
:no_entry: **DO NOT** require a fresh container per operation
772775

773-
#### Authentication
774-
How you secure and protect the data and files that your service uses will not only affect how consumable your API is, but also, how quickly you can evolve and adapt it. Implementing Role Based Access Control [RBAC](https://docs.microsoft.com/en-us/azure/role-based-access-control/overview) is the recommended approach.
775-
It is important to recognize that any roles defined in RBAC essentially become part of your API contract. For example, changing a role's permissions, e.g. restricting access, could effectively cause existing clients to break, as they may no longer have access to necessary resources.
776+
:white_check_mark: **DO** use managed identity and Role Based Access Control ([RBAC](https://docs.microsoft.com/en-us/azure/role-based-access-control/overview)) as the mechanism allowing customers to grant permission to their Storage account to your service.
776777

777778
:white_check_mark: **DO** Add RBAC roles for every service operation that requires accessing Storage scoped to the exact permissions.
778779

779780
:white_check_mark: **DO** Ensure that RBAC roles are backward compatible, and specifically, do not take away permissions from a role that would break the operation of the service. Any change of RBAC roles that results in a change of the service behavior is considered a breaking change.
780781

781-
##### Handling 'downstream' errors
782-
It is not uncommon to rely on other services, e.g. storage, when implementing your service. Inevitably, the services you depend on will fail. In these situations, you can include the downstream error code and text in the inner-error of the response body. This provides a consistent pattern for handling errors in the services you depend upon.
783-
784-
:white_check_mark: **DO** include error from downstream services as the 'inner-error' section of the response body.
785-
786-
#### Working with files
787-
Generally speaking, there are two patterns that you will encounter when working with files; single file access, and file collections.
788-
789-
##### Single file access
790-
Desiging an API for accessing a single file, depending on your scenario, is relatively straight forward.
791-
792-
:heavy_check_mark: **YOU MAY** use a Shared Access Signature [SAS](https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview) to provide access to a single file. SAS is considered the minimum security for files and can be used in lieu of, or in addition to, RBAC.
782+
:heavy_check_mark: **YOU MAY** use Shared Access Signatures [SAS](https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview) to provide access to Storage objects.
793783

794784
:ballot_box_with_check: **YOU SHOULD** if using HTTP (not HTTPS) document to users that all information is sent over the wire in clear text.
795785

796-
:ballot_box_with_check: **YOU SHOULD** support managed identity using Azure Storage by default (if using Azure services).
786+
:white_check_mark: **DO** return an HTTP status code representing the result of your service operation's behavior. If the operation uses Storage internally, this an implementation detail from the client's perspective of the operation but may happen due to a missing Storage object or insufficient permissions. If the internal Storage operation fails, include the Storage error information in the 'inner-error' section of your operation's response body to help the client know that they may have configured their Storage improperly.
797787

798-
###### File Versioning
799-
Depending on your requirements, there are scenarios where users of your service will require a specific version of a file. For example, you may need to keep track of configuration changes over time to be able to rollback to a previous state. In these scenarios, you will need to provide a mechanism for accessing a specific version.
788+
:white_check_mark: **DO** allow the customer to specify a URL path to a single Storage object if your service requires access to a single file.
800789

801-
:white_check_mark: **DO** Enable the customer to provide an ETag to specify a specific version of a file.
802-
##### File Collections
803-
When your users need to work with multiple files, for example a document translation service, it will be important to provide them access to the collection, and its contents, in a consistent manner. Because there is no industry standard for working with containers, these guidelines will recommend that you leverage Azure Storage. Following the guidelines above, you also want to ensure that you don't expose file system constructs, e.g. folders, and instead use storage constructs, e.g. blob prefixes.
790+
:heavy_check_mark: **YOU MAY** allow the customer to provide a [last-modified](https://datatracker.ietf.org/doc/html/rfc7232#section-2.2) timestamp (in RFC1123 format) for read-only files. This allows the client to specify exactly which version of the files your service should use. When reading a file, your service passes this timestamp to Azure Storage using the [if-unmodified-since](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4) request header. If the Storage operation fails with 412, the Storage object was modified and your service operation should return an appropriate 4xx status code and return the Storage error in your operation's 'inner-error' (see guideline above).
804791

805-
:white_check_mark: **DO** When using a Shared Access Signature (SAS), ensure this is assigned to the container and that the permissions apply to the content as well.
792+
:white_check_mark: **DO** allow the customer to specify a URL path to a logical directory (via prefix and delimiter) if your service requires access to multiple files (within this directory). For more information, see [List Blobs API](https://docs.microsoft.com/en-us/rest/api/storageservices/list-blobs)
806793

807-
:white_check_mark: **DO** When using managed identity, ensure the customer has given the proper permissions to access the file container to the service.
794+
A common pattern when working with multiple files is for your service to receive requests that contain the location(s) of files to process ("input") and a location(s) to place any files that result from processing ("output"). Note: the terms "input" and "output" are just examples; use terms more appropriate to your service's domain.
808795

809-
A common pattern when working with multiple files is for your service to receive requests that contain the location(s) of files to process, e.g. "input" and a location(s) to place the any files that result from processing, e.g. "output." (Note: the terms "input" and "output" are just examples and terms more relevant to the service domain are more appropriate.)
810-
811-
For example, in a request payload may look similar to the following:
796+
For example, a service's request body to configure BYOS may look like this:
812797

813798
```json
814799
{
815-
"input":{
800+
"input":{
816801
"location": "https://mycompany.blob.core.windows.net/documents/english/?<sas token>",
802+
"delimiter": "/",
803+
"lastModified": "Wed, 21 Oct 2015 07:28:00 GMT"
804+
},
805+
"output":{
806+
"location": "https://mycompany.blob.core.windows.net/documents/spanish/?<sas token>",
817807
"delimiter":"/"
818-
},
819-
"output":{
820-
"location": "https://mycompany.blob.core.windows.net/documents/spanglish/?<sas token>",
821-
"delimiter":"/"
822-
}
808+
}
823809
}
824810
```
825-
Note: How the service gets the request body is outside the purview of these guidelines.
826811

827-
Depending on the requirements of the service, there can be any number of "input" and "output" sections, including none. However, for each of the "input" sections the following apply:
812+
Depending on the requirements of the service, there can be any number of "input" and "output" sections, including none.
828813

829-
:white_check_mark: **DO** include a JSON object that has string values for "location" and "delimiter."
814+
:white_check_mark: **DO** include a JSON object that has string values for "location" and "delimiter". For "location", the customer must pass a URL to a blob prefix which represents a directory. For "delimiter", the customer must specify the delimiter character they desire to use in the location URL; typically "/" or "\".
830815

831-
:white_check_mark: **DO** use a URL to a blob prefix with a container scoped SAS on the end with a minimum of `listing` and `read` permissions.
816+
:heavy_check_mark: **YOU MAY** support the "lastModified" field for input directories (see guideline above).
832817

833-
For each of the "output" sections the following apply:
818+
:white_check_mark: **DO** support a "location" URL with a container-scoped SAS that has a minimum of `listing` and `read` permissions for input directories.
834819

835-
:white_check_mark: **DO** use a URL to a blob prefix with a container scoped SAS on the end with a minimum of `write` permissions
820+
:white_check_mark: **DO** support a "location" URL with a container-scoped SAS that has a minimum of `write` permissions for output directories.
836821

837822
### Conditional Requests
838823
When designing an API, you will almost certainly have to manage how your resource is updated. For example, if your resource is a bank account, you will want to ensure that one transaction--say depositing money--does not overwrite a previous transaction.

0 commit comments

Comments
 (0)