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.

More Resources

https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-sas#generate-a-shared-access-signature-token

Example GitHub Project

author avatar
Josh Donner Sr. Software Engineer
Josh started writing programs while working as a phone rep for Allstate, and it turned into a career over 15 years ago. He has worked on many different projects, from OCR technology to 3D modeling of buildings to simulating loading steel on trailers for transport. Don’t Panic Labs represents a new chapter in Josh’s life and an opportunity to learn new things.

Related posts