Remote Work Tools

Remote onboarding fails in predictable ways: the new hire waits 2 days for access to be provisioned, nobody tells them how to find anything, and the buddy system is just a name on a doc with no clear expectations. Good remote onboarding is a system, not a checklist.

This guide covers the tooling and process for onboarding remote engineers, with actual templates and automation scripts.

The Access Provisioning Problem

Most onboarding delays come from access. Someone has to manually add each new hire to GitHub, AWS, Slack, the VPN, and twelve other tools. Automate this:

#!/bin/bash
# provision-new-hire.sh
# Provisions a new remote engineer's access
# Usage: ./provision-new-hire.sh USERNAME EMAIL GITHUB_HANDLE TEAM

set -e

USERNAME="$1"      # e.g., alice
EMAIL="$2"          # alice@company.com
GITHUB="$3"         # alice-dev
TEAM="$4"           # engineering

echo "Provisioning $USERNAME ($EMAIL)..."

# 1. Add to GitHub org and team
gh api orgs/your-org/teams/$TEAM/memberships/$GITHUB \
  -X PUT -f role=member

# 2. Add to relevant GitHub repos
for repo in api-service frontend infra-tools; do
  gh api repos/your-org/$repo/collaborators/$GITHUB \
    -X PUT -f permission=push
done

# 3. Create AWS IAM user and add to developer group
aws iam create-user --user-name "$USERNAME"
aws iam add-user-to-group --user-name "$USERNAME" --group-name "developers"

# Generate access keys for CLI use
aws iam create-access-key --user-name "$USERNAME" \
  --query '[AccessKey.AccessKeyId, AccessKey.SecretAccessKey]' \
  --output text

# 4. Invite to Slack workspace via API
curl -X POST https://slack.com/api/users.admin.invite \
  -H "Authorization: Bearer $SLACK_ADMIN_TOKEN" \
  -d "email=$EMAIL&channels=C01,C02,C03&resend=true"

# 5. Add to 1Password team
op user provision \
  --name "$USERNAME" \
  --email "$EMAIL" \
  --role member

echo "Provisioning complete for $USERNAME"
echo "Manual steps remaining:"
echo "  - Add to PagerDuty schedule"
echo "  - Create Jira/Linear account"
echo "  - Add to HR system"

Tool Stack by Category

Documentation:

Communication:

Access management:

Dev environment:

The 30-60-90 Day Framework

Onboarding for a remote engineer should have three phases with different objectives:

Days 1-30: Get oriented

Days 31-60: Build context

Days 61-90: Contribute fully

First Week Checklist (New Hire)

# Week 1 Onboarding Checklist

## Day 1: Access and Orientation
- [ ] Slack: Join workspace, set up notifications, join team channels
- [ ] GitHub: Accept org invite, set up 2FA, clone main repos
- [ ] Dev environment: Clone repo, run `make setup` or `docker compose up`
- [ ] 1Password: Accept invite, save all shared credentials
- [ ] Read: Team handbook (Notion link)
- [ ] Read: Engineering principles doc
- [ ] Meet: Manager 1:1 (30 min — context, expectations, immediate next steps)

## Day 2: Dev Environment Working
- [ ] Run the full test suite locally (confirm it passes)
- [ ] Deploy to staging environment once (follow the runbook)
- [ ] Set up local aliases and dotfiles
- [ ] Explore the codebase: read the README, find the main entry points
- [ ] Meet: Buddy engineer (intro call, 30 min)

## Day 3-4: First Contribution
- [ ] Find a "good first issue" label in Linear/GitHub
- [ ] Make a small change, open a PR
- [ ] Go through the full review cycle for your PR
- [ ] Watch one past incident postmortem (Notion link)
- [ ] Meet: 2 other team members (ask buddy to intro)

## Day 5: Week 1 Retrospective
- [ ] Meet: Manager check-in (15 min — what was unclear? what's next?)
- [ ] Document: Add at least one thing to the onboarding doc that was missing or unclear
- [ ] Set: 30-day goals with manager

First Week Checklist (Manager/Buddy)

# Manager Onboarding Checklist

## Before Day 1
- [ ] Provision all access (run provision script or complete checklist)
- [ ] Assign a buddy (senior engineer, not manager)
- [ ] Create onboarding Notion page with: team contacts, key docs, current priorities
- [ ] Add to all recurring team meetings
- [ ] Notify team in Slack: "Alice joins Monday — please say hello!"
- [ ] Prepare a "good first issue" — tag it in Linear/GitHub

## Day 1
- [ ] Welcome DM in Slack with key links (handbook, calendar, Zoom, etc.)
- [ ] 30-min intro call: team context, expectations for first month, immediate next step
- [ ] Confirm all access is working (ask them to verify)

## Day 3-5
- [ ] Buddy: check in — is the dev environment working?
- [ ] Review their first PR promptly (within 24h — sets the tone for code review culture)
- [ ] Share: relevant recent architecture decisions (ADR links)

## End of Week 1
- [ ] 15-min check-in: what was unclear? what do you need next week?
- [ ] Update onboarding doc with any gaps they found

Buddy System Setup

A buddy is a peer engineer (not the direct manager) who is the new hire’s first point of contact for questions. The buddy relationship needs structure to work asynchronously:

# Buddy System Expectations

## Buddy responsibilities (first 4 weeks)
- Daily check-in Slack message: "How's it going? Anything blocked?"
- Available for a 30-min pairing session within 24h of request (via DM)
- Review the new hire's first 3 PRs with extra context (explain the "why" not just the "what")
- Proactively share context: "We're about to do X — here's why and what to expect"

## What the buddy is NOT
- Not a blocker for the new hire (they can ask anyone)
- Not responsible for their performance
- Not on-call for them 24/7

## Time commitment
- Approximately 2-3 hours per week for the first month
- Tapers off in month 2

## Buddy meeting agenda (first week)
1. How's setup going? What's working, what's not?
2. Quick codebase tour (30 min screen share or Loom walkthrough)
3. Who's who: key people and their roles
4. Unwritten rules: how we actually work (communication norms, deploy process, on-call rotation)

Automating the Onboarding Progress Check

#!/usr/bin/env python3
# check-onboarding-progress.py
# Checks GitHub for a new hire's first contributions and posts status to Slack

import requests
from datetime import datetime, timedelta

GITHUB_TOKEN = "ghp_XXXXXX"
SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK"
ORG = "your-org"
NEW_HIRE_GITHUB = "alice-dev"
START_DATE = "2026-03-21"

def check_contributions():
    headers = {"Authorization": f"token {GITHUB_TOKEN}"}

    # Check for PRs opened
    prs = requests.get(
        "https://api.github.com/search/issues",
        params={
            "q": f"org:{ORG} is:pr author:{NEW_HIRE_GITHUB} created:>={START_DATE}",
        },
        headers=headers
    ).json().get("total_count", 0)

    # Check for PR reviews given
    reviews = requests.get(
        "https://api.github.com/search/issues",
        params={
            "q": f"org:{ORG} is:pr reviewed-by:{NEW_HIRE_GITHUB} created:>={START_DATE}",
        },
        headers=headers
    ).json().get("total_count", 0)

    days_since_start = (datetime.now() - datetime.strptime(START_DATE, "%Y-%m-%d")).days

    payload = {
        "text": f"*Onboarding check — {NEW_HIRE_GITHUB} (Day {days_since_start})*\n"
                f"• PRs opened: {prs}\n"
                f"• PRs reviewed: {reviews}\n"
                f"{'✓ On track' if prs > 0 else '⚠ No PRs yet — check in'}"
    }

    requests.post(SLACK_WEBHOOK, json=payload)

check_contributions()

Built by theluckystrike — More at zovo.one