Sometimes the simplest problems lead to interesting workarounds.
In my case, I needed to upload files into Box, but Box.com was blocked on the network I was on. Direct uploads through the Box web UI weren’t an option. On the other hand, the AWS Management Console and S3 were fully accessible.
That got me thinking: what if I use S3 as a staging ground? Whenever I upload something to S3, an AWS Lambda function could automatically push it into Box. This way, I don’t need to touch Box directly from my blocked network.
The High-Level Flow
Here’s how the pieces fit together:
+---------+ (Upload file) +-------------+
| | ----------------------------> | |
| User | | S3 |
| | <---------------------------- | Bucket |
+---------+ (Accessible) +-------------+
|
| (Event Trigger)
v
+-------------+
| Lambda |
| Function |
+-------------+
|
| (Upload via API)
v
+-------------+
| Box |
| Folder |
+-------------+
Challenges
Setting this up wasn’t entirely smooth sailing. I struggled especially with:
Python 3.11 on Mac: Lambda runs on Python 3.11 by default, so I wanted my local packaging environment to match. But installing Python 3.11 on macOS via Homebrew took much longer than I thought, as the
python3commands didn’t always point where I expected. It took some fiddling with my.zshrcand symlinks before I could getpython3andpip3aligned properly.Packaging the full
boxsdklibrary for Lambda may require a Amazon Linux environment, not macOS. Hence I didn’t proceed on to switch to using on-demand JWT tokens.
Steps at a Glance
Prepare an S3 bucket to act as the upload staging area.
Create a Lambda function that listens to S3 “object created” events.
Use a Box Developer Token (short-lived) to authenticate uploads to Box.
Package and deploy the function with its dependencies.
Upload a file to S3 and watch it appear in Box automatically.
What Worked Well
AWS accessibility: even though Box.com was blocked, S3 and Lambda were fully reachable.
Developer Token: made testing fast and simple.
Event-driven flow: uploads happen automatically — no manual intervention.
Final Thoughts
With more time, the next logical step would be moving from a quick proof-of-concept into a production-ready setup — one that uses a JWT or OAuth 2.0 app with automatic token refresh to keep the integration running reliably.
On a broader level, this little project reminded me that many of the frustrations we face day to day can actually spark creative solutions. Often, a bit of “vibe coding” experimentations, stitching together services, and seeing what clicks can turn a roadblock into something genuinely useful, not just for yourself but potentially for others too.

