Starting with a fresh MacBook can be exciting, but navigating corporate IT requirements can feel daunting. This article demystifies the process with a step-by-step guide so you can set up your machine smoothly and in line with company policy, and stay productive from day one.
This article focuses on a Python developer persona, but most of it applies to any developer.
A corporate MacBook
Depending on your company, the MacBook provided as a developer workstation can be harder to work with than a privately owned MacBook.
Namely:
- You will not have
sudoon your workstation. - A proxy may be required by company policy.
Not having sudo is the main constraint; we will see how to work within it and still comply with policy—that means we will not bypass controls, but we will use what macOS allows.
Homebrew
Homebrew is the go-to package manager for developers on macOS. It plays a similar role to apt on Ubuntu.
The official documentation expects sudo for the default install. You can also install it for your user only with:
mkdir $HOME/homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
This creates a homebrew directory under $HOME where Homebrew is installed.
Add it to your PATH permanently. In the rest of this article, zsh is assumed as your shell (but you can use any shell you prefer).
echo 'export PATH=$HOME/homebrew/bin:$PATH' >> ~/.zshrc
Check that Homebrew works
The following command applies the PATH change in your current terminal:
source ~/.zshrc
The next command should print a version and confirms Homebrew is installed and usable:
brew --version
CLI tools
Install a first tool:
brew install git
You can install other developer tools available as Homebrew formulae; they are installed for your user without sudo.
GUI applications
GUI apps need an Applications folder. By default, Homebrew Cask targets /Applications at the root of the disk, which you may not be allowed to write to.
For example, try OpenLens—a tool that provides a UI to inspect your Kubernetes cluster. It is available as a Homebrew cask.
If you run:
brew install --cask openlens
that install can fail because Homebrew cannot use /Applications.
Instead, create an Applications folder under your home directory:
mkdir $HOME/Applications
Then tell Homebrew to use it:
brew install --cask openlens --appdir $HOME/Applications
You should be able to open OpenLens from Spotlight. You can install GUI apps this way without sudo.
Rosetta
Sometimes you need a specific CPU architecture for a binary (either Apple silicon or Intel).
Apple silicon (M1, M2, M3, M4) Macs use arm64 natively. Rosetta lets you run x86_64 binaries. That helps when libraries exist only for one architecture; x86_64 is older, so binaries are often available there first.
You can add aliases to start a shell under Rosetta or natively. Add these to your .zshrc:
alias arm="env /usr/bin/arch -arm64 /bin/zsh --login"
alias intel="env /usr/bin/arch -x86_64 /bin/zsh --login"
To see which architecture your current shell is using, run:
arch
You should see either i386 (Intel / Rosetta) or arm64 (Apple silicon).
Installing language-specific tools
To manage multiple versions of Python, Node, the AWS CLI, Cargo, and more, this guide uses mise.
You can run two setups—one native and one under Rosetta—so environments match each architecture, as described in the mise macOS Rosetta notes.
Follow that installation path; you should then have the x86_64 binary available as:
mise-x64 --version
You can also use the standard arm64 mise from Homebrew if you do not need x86_64-specific toolchains:
brew install mise
You can then install Python, Node, and many other tools with mise.
Example: install Python for an x86_64 toolchain:
mise-x64 use python@3.10
Containerization tools
For containers, several options exist.
The most common is Docker; open-source alternatives such as Podman exist as well.
Installing PHP
It is a bit fiddly, but doable: you can use mise-x64 as follows:
PHP_CONFIGURE_OPTIONS="--with-openssl=$(brew --prefix openssl) --with-iconv=$(brew --prefix libiconv)" mise-x64 use php@8.4 --global
Because ARM support can be limited, an x86_64 build is often more reliable here.
Docker
You will usually need IT to install Docker Desktop, because it requires elevated privileges.
Podman
Podman can replace Docker for many workflows and does not require the same elevated setup. Install it with Homebrew or follow the Podman Desktop macOS installation guide:
brew install podman
You can alias podman to docker for convenience in your .zshrc:
alias docker=podman
The Podman CLI is largely compatible with the Docker CLI.
Try:
docker run hello-world
On first use you may need to initialize the Podman machine:
podman machine init
podman machine start
See the Podman Desktop macOS troubleshooting page if something fails.
Disclaimer: Some stacks, such as Testcontainers for Python, expect a real Docker daemon and may not work fully with Podman. podman-mac-helper and socket compatibility can help, but that often still needs cooperation from IT.
Proxies and certificates
Your company may use an HTTP proxy with its own TLS certificate. This section skips why that exists and focuses on how to work with it.
Tools such as the Azure CLI may fail until trust is configured; see Azure CLI: work behind a proxy. That example is a good check that your proxy and certificates are set up correctly.
As documented, set REQUESTS_CA_BUNDLE to the path of your combined CA bundle. The same idea applies when Python tools need HTTPS access to install dependencies.
Creating a certificate bundle
Build one PEM file that merges system and corporate roots; you will point tools at it.
Create a directory and an environment variable:
mkdir $HOME/certs
echo 'export CORPORATE_CERT_DIR=$HOME/certs' >> ~/.zshrc
Export certificates from the keychains and concatenate them into allCAbundle.pem:
security export -t certs -f pemseq -k /Library/Keychains/System.keychain -o $CORPORATE_CERT_DIR/selfSignedCAbundle.pem
security export -t certs -f pemseq -k /System/Library/Keychains/SystemRootCertificates.keychain -o $CORPORATE_CERT_DIR/bundleCA.pem
cat $CORPORATE_CERT_DIR/bundleCA.pem $CORPORATE_CERT_DIR/selfSignedCAbundle.pem >> $CORPORATE_CERT_DIR/allCAbundle.pem
To inspect the file:
cat $CORPORATE_CERT_DIR/allCAbundle.pem
Using the bundle
Append exports to .zshrc. Different tools use different variables; setting several covers most cases:
echo 'export REQUESTS_CA_BUNDLE=$CORPORATE_CERT_DIR/allCAbundle.pem' >> ~/.zshrc
echo 'export SSL_CERT_FILE=$CORPORATE_CERT_DIR/allCAbundle.pem' >> ~/.zshrc
echo 'export CURL_CA_BUNDLE=$CORPORATE_CERT_DIR/allCAbundle.pem' >> ~/.zshrc
echo 'export NODE_EXTRA_CA_CERTS=$CORPORATE_CERT_DIR/allCAbundle.pem' >> ~/.zshrc
After that, az and typical package managers (uv, poetry, npm, etc.) should work through the proxy.
If you are off the corporate network and the proxy is disabled, you may need to unset these variables (for example unset REQUESTS_CA_BUNDLE) before commands like az login, depending on your environment.
Java specifics
The JVM uses its own trust store. You can import a PEM into a JKS with keytool.
You can run keytool from a container so you do not install a full JDK locally if you prefer not to.
The following example mounts your cert directory and runs keytool inside an image that already ships Java (here apache/spark; any image with keytool is fine):
docker run -v $CORPORATE_CERT_DIR:/opt/java/openjdk/lib/security/jssecacerts -it apache/spark keytool -import -v -trustcacerts -alias endeca-ca -file /opt/java/openjdk/lib/security/jssecacerts/my_custom_certificate.pem -keystore /opt/java/openjdk/lib/security/jssecacerts/truststore.ks
You cannot point keytool at the merged allCAbundle.pem in every case—you often need a single PEM for the corporate issuing CA. Export the right certificate from Keychain Access or your IT docs.
Example lookup:
security find-certificate -p -c "corporate_proxy_name" /Library/Keychains/System.keychain
Then export it:
security find-certificate -a -c "corporate_proxy_name" -p /Library/Keychains/System.keychain >$CORPORATE_CERT_DIR/my_custom_certificate.pem
Or obtain it from a TLS handshake (adjust host and options to match your environment):
curl -w %{certs} https://example.com > $CORPORATE_CERT_DIR/my_custom_certificate.pem
Import with keytool as above; you will be prompted for a keystore password.
Point the JVM at the JKS when you run apps, for example:
-Djavax.net.ssl.trustStore=/opt/java/openjdk/lib/security/jssecacerts/truststore.ks -Djavax.net.ssl.trustStorePassword=your_password
Storing paths and passwords in environment variables (without committing secrets) keeps builds repeatable:
echo 'export CORPORATE_JKS_CERT_PATH=$CORPORATE_CERT_DIR/truststore.ks' >> ~/.zshrc
echo 'export CORPORATE_JKS_CERT_PASS=your_password' >> ~/.zshrc
Docker and corporate TLS
At build time
When you docker build, the build may also need your CA bundle for HTTPS.
You can pass files in with BuildKit --build-context, for example:
docker build -f your_dockerfile --build-context config=$CORPORATE_CERT_DIR your_docker_context
In the Dockerfile, mount that context and set SSL_CERT_FILE / related variables before apt-get or similar:
RUN --mount=type=bind,from=config,target=/tmp/certs \
export REQUESTS_CA_BUNDLE=/tmp/certs/allCAbundle.pem \
&& export SSL_CERT_FILE=/tmp/certs/allCAbundle.pem \
&& export CURL_CA_BUNDLE=/tmp/certs/allCAbundle.pem \
&& apt-get update && apt-get install -y git
At runtime
If a container needs the corporate CA at runtime, mount the PEM and append it to the image trust store in an entrypoint, or bake it in during build—what follows is one illustrative pattern:
docker run -it -v $CORPORATE_CERT_DIR/my_custom_certificate.pem:/certs/my_custom_certificate.pem postgres /bin/bash -c "cat /certs/my_custom_certificate.pem >> /etc/ssl/certs/ca-certificates.crt && /bin/bash"
(Adjust paths and base image to match your stack.)
Conclusion
Hopefully this helps you stay compliant with corporate constraints while remaining productive.
If something is unclear or a topic is missing, say so in the comments.
Update (2026-04-18): Added Java and Docker notes for proxy certificates, and PHP installation. Proof reading
Top comments (0)