Before we jump into how S3 supports signed URLs, let's cover briefly what S3 is and why it's one of the foundational services in AWS.
S3 is an object store where files of any sizes can be uploaded to so-called buckets. It resembles a filesystem but it's not as there are no directories only common prefixes that the AWS Console shows in a hierarchical view.
The objects can be of any size from the tiny log entry to a massive data dump. Also, objects can have additional metadata attached to them, such as a content type or cache control headers, but applications are free to define custom tags.
Why S3 is used in many applications is its guarantees on durability (objects won't be lost) and availability (they can be accessed). In practice, you can drop an object into a bucket and you can be reasonably sure that it will be there. Also, it scales to any load, so you don't even need to think about access patterns. Because of these, it fits well into the serverless application pattern.
A typical serverless application needs some resources for compute, which is usually a Lambda function, a database that is either DynamoDB or RDS, and an API, usually CloudFront. But when that app needs to store files that might not fit into the database, then the logical choice is to store them in an S3 bucket and put just a reference into the main database.
The architecture diagram of the example app that we'll build in the Serverless example app chapter shows this:
Access to buckets and objects are controlled by IAM policies. That makes it possible to restrict who can read and write objects in a granular level. In practice, that usually means some identity (such as a Lambda function) has read and write access and another identity can only read. But it's equally possible to define permissions based on prefixes, roughly emulating directory permissions.
As an example, this statement grants read access to a bucket: