
SAS Style Secure Links: Now with more Bit Shifting!
SAS stands for Shared Access Signature. A SAS style link is a URL that contains parameters needed by the API call as well as a signature that verifies the parameters in the link are correct and haven’t been tampered with. These links can be made to expire, and the key used to create the signature is never passed as part of the URL.
Typical SAS links can have any number of parameters. In the context of a SAS (Shared Access Signature) link, the parameters typically can include the following in addition to any other parameters you may wish to add:
- sp – specifies the permissions granted by the SAS token (e.g., read, write, delete).
- se – the expiration time of the SAS token.
- sr – specifies the resource type (e.g., blob, container).
- sig – a cryptographic signature that ensures the integrity and authenticity of the SAS token.
- st – the start time for the SAS token’s validity period.
- si – a unique identifier for the SAS token.
- sv – the version of the SAS token.
- spr – specifies the allowed protocols (e.g., HTTPS only).
- sip – specifies the IP address or range of IP addresses from which the SAS token is valid.
Note that not all of these are required, but at the bare minimum you should include permissions (sp), expiration (se), and obviously the signature (sig) parameters.
Link Creation
SAS links can be created and consumed by anyone who has the secret key used to generate the signature attached to the link. For example, an API endpoint generates a link that points to another endpoint in the same API that requires validation while allowing the link to be shared (such as emailed to a client). The payload for the link is a simple string, but you can include whatever other information you require.
Link Validation
SAS links are validated by pulling the HttpRequest
apart, retrieving the parameters passed in, and validating them against the signature included. In our example, the function for validation only checks to make sure the signature matches the incoming parameters; it is left up to the caller of the validate function to check things like expiration date and permissions.
Bit Shifting
Bit shifting is used here for the permissions flag in the token creation because of the unique properties of bit shifting, namely that you can include multiple permissions within the same parameter of the function. For each parameter in the SasPermissions enum, the value 1 is bit shifted an amount to indicate the position in the integer that the flag represents. Parameters can be combined using the bitwise OR operator ( | ) to combine the bits of the two values into a new value that can then be queried for permission values.
For example, the Read permission is 1 bit shifted 0 places:
00000001
The List permission is 1 bit shifted 3 places:
00001000
If you combine the Read and List permissions using bitwise or like this:
SasPermissions.Read | SasPermissions.List
You get this resulting integer, which is the decimal number 9:
00001001
To check if something has the specific permissions you require, you use the bitwise AND operator (&) to compare the value with the permissions you want. The AND operator combines the permissions strung together and creates a new number that only has 1’s where both values have a 1.
As a reminder, our permissions include Read
and List
, which is represented as:
00001001
If we use the bitwise AND operator to compare the permission Read
with the above, we will get the result of 1. Anything not zero means that the permission exists.
00001001 // Read | List
00000001 // Read
Result: 00000001 // Read property found
00001001 // Read | List
00001000 // List
Result: 00001000 // Read property found
00001001 // Read | List
00000010 // Write
Result: 00000000 // Write property not found
We use bit shifting here to make the code more elegant. We could accomplish the same thing with an enum of all possible combinations, but the list of options would be much longer. For example, if we wanted Read
, Write
, and Execute
permissions but needed to include all combinations we would need Read
, Write
, Execute
, ReadWrite
, ReadExecute
, WriteExecute
, and ReadWriteExecute
. Every time you add a new permission, you will need even more options added. With bit shifting, you can add one new permission and that is the only change needed.