BSides SF 2023: No Adversaries: Getting Users on Your Side for Tough Transformations

This is the blog post version of my talk with Amy Martin, Project Manager, SF Digital Services, on April 22, 2023, at BSides San Francisco. Video to come. Slides are here.

Every security initiative has two sides. One is purely technical: we need to prevent abusive emails from getting into company inboxes with a product, or we need a code scanner built into CI/CD to look for common insecure patterns in new pull requests. All of these, even those that seem purely like a matter of automation once they’re set up, also have a second side: the people involved.

We’ve both dealt with the human side of implementing security-related processes. Breanne has grappled with it as a site reliability engineer working to refine IAM roles and as a security engineer creating and refining processes around evaluating and approving Chrome extensions and GitHub Actions. Amy has encountered it while pushing technical advances needed to get ahead of software EOL dates and standardize CMS usage among teams who depended on stability to do their jobs. Both of us have learned the value of creating change through policy and process without making everyone hate you.

To that end, we’re using the term users a little differently than usual. Often, this refers to end users, people using your company’s product, the public, or anyone on the outside who needs what we create. What we’re discussing here certainly affects them too, but our focus here is on internal users: partners within our organization, people who depend on our work to get their work done, and people who need to buy into what we’re doing in order to make a better, more secure experience for them and everyone else. Without them, no security transformation will ever truly work.

Two failures, and hope

In January 2022, Amy left her public library job and joined the Delivery team at San Francisco Digital Services. They needed to move about 80 websites off their Drupal 7 platform and onto SF.gov, the City’s unified and accessible website, in advance of the planned end of life of Drupal 7. That was meant to be in November 2022 and did not happen, but that’s another story.

When Amy started at Digital Services in January, about a third of these departments didn’t know yet that they had to move their website by November, and many of them liked their current, government-speak oriented websites just fine. SF.gov is built for usability and accessibility, and plain language is key—not government speak. Every site they moved required content redesign, and Department staff had to be trained to do the work

How can government Digital Service staff convince civil servants and other agencies to embrace digital transformation in the face of a big unwanted project?

The short answer is that they only did part of that. They moved the websites before their deadline, and they got people started on building user-centered websites and writing in plain language. However, most did not continue that work. Some of them even got rid of the content that we made for them and pasted their old content back in.

Although they met our goal of moving the websites by the deadline, they found that they had fallen short of setting government agencies up for future success with user-centered websites

Breanne’s story is from a few jobs ago, before security engineering, when she was an SRE with an interest in security. The company saw its first rash of phishing attempts: texts and emails posing as executive staff, asking for sadly normal things: Google Play gift cards and other easily sold gift cards, urging the recipients to please move quickly, because the gift cards were needed now now now.

Breanne and a colleague teamed up to write both a presentation and written training to let people know what these attempts looked like and to establish company norms around communication so that it would be clearer to everyone what legitimate company communication looked like.

The company had fewer than 100 people then, so it made more sense to write a single version of the training that would serve both the engineering department and other staff, including sales and marketing. The distinction here is less to do with who is or isn’t “technical” and whose jobs depend on answering unknown numbers and replying to texts and emails from strangers.

How could two engineers write a workable, concise anti-phishing guide for everyone? How can it go wrong? In our case: not everyone is experienced at writing precise, well-grounded documentation about a complex subject for a varied audience. In our case, they got the job done, but they bumped into some of the limitations of trying to write something about a very specific topic that’s meant to be for everyone.

How can a project’s start doom it?

It’s good to start as you mean to end, which means that thinking of what makes a project like this successful from the start goes a long way toward ensuring its success. So what gets baked into a project plan that can doom it to failure?

Maybe your planning doesn’t entirely account for reality. Maybe your engagement doesn’t account for the real needs limitations and motivations of your users
Or maybe it’s meteor from space or other things outside our control. (This probably felt way less possible before March 2020. Now it’s a pretty good idea to write “large scale crisis” into every risk plan.)

We can’t control everything, but we can control some things. What can we do?

Remember that your partners are users too. Keeping this in mind prevents a lot of issues. Like with end users, it’s worth your time to get to know your internal users’ motivations, limitations, and wants, as well as their hard NOs: things they absolutely will not tolerate.

Seek the similarities. See what behaviors, preferences, and common experiences make groups of users start to cohere in your interactions with them. If your team is having trouble wrapping their heads around this, consider using a lightweight version of personas. Rather than the more involved versions used in marketing and UX, we don’t need to know anyone’s educational level, income, or other demographic information, though it’s not unlikely that some of these divisions will fall neatly between job titles or departments. Instead, look at what’s going to affect your plans:

  • What tools are they familiar with? What tools that you’re asking them to use might they not have encountered before?
  • Do they work with security a little or often? If they hear from security via a direct message or an email, will their first thought be that they’re in trouble?
  • Are they amenable to change or resistant? If they’re resistant, why? (This is a really important question to answer.)
  • What motivates them? What’s their definition of professional success?

Avoid stereotypes or unhelpful guesses. Making them too artificial or overly specific is also more likely to harm than help. If it’s just you and a colleague working on this project, it can be plenty to discuss the groups you’re seeing form and plan based on that. However, if you’re doing a longer project or perhaps a larger body of work, you may wish to write them down to share, shape, and reference.

Encountering resistance? Slow down. When you’re starting to roll out your initiative, you may encounter resistance. If the resistance is starting to threaten the velocity or the success of what you’re trying to do, tap the brake and regroup. Form a new hypothesis or think of another strategy—and then seek feedback from the group that wasn’t feeling served before. This is extremely important to do, because we can’t afford to guess in these situations. Fortunately, when you deputize people, they often want to step up and help. If I think someone will be reluctant, I tell them that they hold a key to my success that I can’t under any circumstances produce myself. It’s important to mean this when you say it, but fortunately, it’s completely true, so that shouldn’t be hard.

Make it easy for people to do what you want. Breanne talked about this in her BSides SF talk on documentation last year. Some of the same tactics apply here too: bribery is a legitimate option to overcome some objects. Everyone likes stickers and snacks. However, we can do a little better than that too.

Don’t make users wade through extra reading, video, or other hurdles to do the important thing. Make what you need them to do succinct, clear, and as easy to do as possible. Clear instructions help a lot, as do easy contacts to ask for help. Have the critical stuff up front if you’re asking people to take in information. Executive summaries, a block of text or page or two at the front of a longer document, make sure that busy people have an easier time learning what they need. In longer trainings, the occasional tl;dr block can let people with different attention spans hopscotch through without missing the critical stuff.

This is also a great time to think again of accessibility. (Although it’s always a great time to think about accessibility.) It’s the right thing to do and often legally mandated, but it has one more useful effect, which is that it makes it easier to reach different kinds of learners too. Breanne can hear a video but vastly prefers reading, so a video with transcription reaches those with hearing difficulties as well as those who just like reading, those who can’t turn the sound on, and those who just need to CMD-F or CTRL-F to find the one detail they need to do their job.

This is also a good time for another look back, because history can teach us something. Previous efforts may not be perfect, but they may contain practices and approaches that people are already used to, which means they won’t have to do extra work to learn what you’re doing. It may serve your project well to add additional steps and methods of outreach, but if part of the old approach is getting you a good amount of the way there, it’s likely worth keeping. Security doesn’t have the luxury of perfection a lot of the time, but we can do an 80 percent job in several different ways and achieve something closer to it than we would otherwise.

When you’re asking about the history of projects at your organization, make it clear that you actually want to hear real opinions and that there won’t be retaliation or sore feelings if someone confesses a negative opinion about something that came before.

If all else fails, come back to bribery: security skills look good on resumes, even if the person doesn’t work in security. Try getting people on your side to help them master something important or lucrative. This creates allies.

Okay, but why do we need to think about this at all?

Why do we need to think about this? Aren’t people used to security initiatives and communication around them being subpar or even extremely disruptive? Security is important, and shouldn’t that be enough?

Yes, but—people are part of the system too, and if you’re looking to change the system in an effective and lasting way, you need to work the people part of it too. Both people and the non-people part of systems work better if you give them what they need.

People will not adopt the changes you recommend if you don’t make it easy, explain it well, and make the preferred behavior the easy path. Technical motivations have human implications. It’s just true, and until we reach the robot-controlled singularity, this is just how it’s going to be. We have to adapt.

No matter how brilliant your new security solution, clever process, or other big idea is, it will not work as well as you want it to unless people are on your side. Worse still, you might get a false sense of success as people initially go through the motions of doing what you wanted… only to revert to old habits the next time work gets stressful. We’re looking for something more robust than superficial change.

Once more: how do projects fail?

Projects fail if you don’t get buy-in. This doesn’t need to be unanimous support and a company pep rally celebrating how great your project is. It can be as simple as sending a series of emails ahead of time letting people know what’s coming, when changes will happen, and what they need to do. A little consideration goes a long way.

Projects fail when large, disruptive projects, even ones for the benefit of security, are pushed into being without considering how they affect the people who depend on efficiency or otherwise prefer the previous system for good reason. If people are reluctant, we need to know why and to address that.

Possibly worst of all, projects fail when they’re rotted from the inside by contempt for users and other affected parties by those in power. All of your future efforts will be diminished if the people you’re supposed to be serving can tell you think you’re smarter than them, better than them, or a greater authority on their own lives. People hate this and remember it, and you will face increased friction forever if you get up to this kind of thing. So don’t.

How can we fix this?

Unless you’re Ben Affleck and company, we can’t stop a meteor on a collision course with earth, but there are other levers we can pull to make our projects go smoothly.

Going back to story time: Breanne’s anti-phishing presentation had some things to learn. It couldn’t be too long: people are busy. It needed a short, memorable set of guidelines. It needed to relate causes to effects: “If we don’t present a unified front in not answering phishing texts and looking more carefully at emails, we’ll keep getting hit, and that will have an effect on the business.” It needed to be informed by technical needs but without including too much jargon, because most people who needed anti-phishing guidelines didn’t need to know about how spam emails sneak by Gmail’s spam-targeting AI. Technical curiosity is worth indulging, but it was better as a leave-behind piece for those who want it, leaving the rest of the audience free to go back to their regular work.

Amy’s SF.gov migration is still a work in progress. A lot of their work in 2023 has been around evolving practices and platforms to help their users experience digital transformation. Here are some of their guidelines for that work:

Consider accessibility and cultural differences.
Amy is working on the accessibility of the artifacts she creates and becoming more flexible with the formats and platforms she puts them into. City government is a Microsoft house, and it’s not her team’s preferred set of tools, but many of their users are wary of anything else or simply aren’t allowed to use other products.

Emphasize common ground.
Amy’s background is outside of tech. When she talks with users, she leads with her government background, which allows her to show users their similarities. She makes it a point to visibly not understand things and ask questions, to normalize those behaviors to make others more comfortable.

Say things the easy way.
On SF.gov, they write in plain language, but it can be hard to remember to do that with their users too. If what you need to say is written down, put it into hemingwayapp.com and try to lower the reading level using their suggestions.

Avoid tech jargon and business jargon.
When you need to introduce a technical term, level-set by saying “do you already know the word ____?” Give them a chance to say yes or no, then explain it if they don’t.

Use nonjudgmental language.
Rather than calling something “bad” or another derogatory word, explain the pros and cons. Try to be precise about what you’re pointing out so that you are not expressing judgment. That goes tenfold for anything that your user currently uses or wants.

Speak at a comfortable pace for your audience.
Watch for facial expressions that look worried, like wrinkled foreheads: that could mean people are concentrating hard to keep up with you.

Maintain neutral facial expressions.
Amy does not laugh and does not smile when people ask tech questions. Every question is valid, and every question, especially a very basic or exceptionally strange question, gives you information about what that person needs to know from you.

We sometimes think a smile will be reassuring, but consider that even a reassuring smile can convey “I know the answer and you do not”. As we mentioned earlier, you do not want to give even the appearance of thinking of yourself as smarter than the other person, because that is extremely sensitive and it will be clocked.

Listen actively.
Repeat back what you’re hearing. Paraphrase, but not with tech jargon, because that will sound like you’re correcting them.

Celebrate mastery.
The first time Amy ever felt confident, good, and proud when using a tech tool was in an intermediate Excel class. Amy is not an Excel master, but “confident, good, and proud” is the feeling of mastery. When Amy sees a user experiencing a feeling of mastery, she parties with them, no matter how small a thing it’s for. Amy saw a user feeling mastery because she learned the keyboard shortcut for paste. They celebrated her success as a team, and they’re still a team.

Question your assumptions about your users.
A little humility truly does go a long way. When you don’t understand what your users are doing or why they want what they want, you could try the five whys, because asking why five times can lead you to the real problem.
Example: a tech product that library bought, failed to adopt, and canceled within a year.

  • Why did we fail to adopt the product? Staff never made it part of their workflow.
  • Why was that? They had trouble training and onboarding everyone.
  • Why was that? Rolling out new software to busy front-line staff is very hard, and they did not set aside enough of everyone’s time to make the training stick.
  • Why was that? The software wasn’t seen as enough of a priority to take people away from public service.
  • And why was that? Well, one person in leadership signed a contract for the software despite every other person saying it wasn’t a good fit for the library.

Answer: lack of buy-in.

Try it out and find a version of it that works for you. Sometimes it’s a good tool to use when you find yourself feeling annoyed by the users you’re meant to be serving.

Ask like a librarian: use reference interviews.
Amy was a librarian for 17 years and wants to teach you about reference interviews. When you go to a library and say can you help me find a book, that is the beginning of your reference interview. In this interaction, a trained librarian is assessing:

  • The words you chose
  • Whether there was hesitation in your voice
  • Your body language
  • Tone
  • The way you approached them
  • What else you are holding in your hands 
  • And more

A secret of reference interviews: the cover isn’t blue. Amy has been surprised, in the tech world, by how literally people take requests from users. There’s a librarian adage about “the book with the blue cover.” Asking for things inaccurately is expected behavior. Not because people are lying or not smart, but because this is the way human brains work: imprecisely. 

A good reference interview helps a person form their question. Try tangential lines of questioning. When you’re looking for the book with the blue cover, it’s tempting to keep asking about the cover. Is there a picture? Light blue or dark blue? 

Don’t bother. The cover is irrelevant. 

Ask questions about something else. When did you read the book? In the 70s? Last year? Was it a book you were assigned in school? Did you get it at a Scholastic book fair? Was the main character an animal or a person? Amy uses a mix of broad and specific questions to try to snag on some detail that triggers a new, meaningful memory. The same technique can work for zeroing in on product requirements. 

Learn user vocabulary and motivations.
Every question is valid. A question might sound silly to you, but it is not silly to the person asking. If you are a knowledge authority figure, chances are they had to screw up their courage to ask you.


Keep a neutral facial expression.
We won’t tell you not to smile, but remember that a smile can read as condescending.

Get to know their vocabulary, and use it.
People often adapt their language in ways they assume make sense to us when they ask questions. They use vocabulary they’ve heard people in our position use. They focus on a detail that’s related to what they want because they associate that detail with techy people.

A common example of this in tech is a user who insists on a particular feature, but has an inaccurate understanding of what it does. They know what outcome they want, but ask for a thing that won’t get them that outcome. Why? Because they are trying to communicate the outcome to you in what they assume is your language. Repeating what users said and paraphrasing, in addition to being good active listening, gives them a chance to edit and refine their ask. Listen to the vocabulary your partners use and use it too.

Be wary of contempt.
If you work with anyone who expresses contempt for your user, be very wary of them. All users are beautiful, but some are harder to reach. If you don’t like working with users and find yourself disdainful of their needs, consider that in your career path. You have more than one kind of user and they are all important.

Tie directives to outcomes your users value.
They may not be the same outcomes you value! Find common fears and desires among the users you’re meant to serve and appeal to them, ideally leaning more on the desires than the fears. It’s better to only reference the scarier things (“If we don’t complete this initiative, we’ll have our government certification pulled, and we will all be unemployed”) only with people who know you well. Instead, try invoking more immediate stakes. Breanne likes “I don’t want you to get a phone call at 3 AM if something goes wrong, because everyone understands that.

Takeaways

  • Work to understand actual motivations behind resistance.
  • Learn to speak the user’s language: vocabulary, accessibility, and technological knowledge.
  • No dictates without relating them to your user’s actual needs and priorities.
  • Try reference interview secrets to understand the bigger picture.
  • Helping people to master something important/lucrative will get them on your side.

Further reading

Yum and ldapsearch: a Lesson for 28 April

Source

The question of how to install things still trips me up sometimes. There are a bunch of possible ways it could be done in any given situation, and fairly often, the preferred method isn’t detailed overly meticulously in the README or other docs. Sometimes you have to clone repos and run a certain command in that directory; sometimes it means adding something to /usr/bin and opening a new terminal window; sometimes you summon a UI with a texty terminal command, which feels oddly like sorcery to me.

It’s a good deal easier now, but when I was just starting it could be a real trial. I spent a lot of an afternoon at Hackbright struggling with Postgres because I did a brew install instead of Postgres.app, which… did not get me what I needed and introduced a host of other problems. (It did get me a really interesting philosophical kind of conversation about the pros and cons of installing things from too high a level, courtesy of a teacher who became my friend – who still semifondly recalls that time she had to unpick what fuckery I’d wrought in such good faith.)

Today, trying to figure out how to get the command ldapsearcavailable to me, I learned one thing and was reminded of another.

  1. I learned yum whatprovides */$WhatYouSeek. (Thanks, Server Fault.) In my case, ldapsearch was one of several commands inside a differently named package: openldap. Oho. (It’s actually in a couple different families of packages, but I do not need to get Perl up in my business today.)
  2. I was reminded that – less commonly for the kind of work that I do – sometimes the needed command is not the name of the package. Some packages aren’t all about one command doing one thing well, despite the best urgings of the Unix philosophy. So – ldapsearch is snuggled into openldap. Got it.

Now you’ve got it too.

11 Lessons from My First Year in Software Engineering

Paper garlands against a twilit sky

I hit my one-year anniversary as a software engineer in October. It has been, professionally, one of the harder, stranger years of my life, but the challenges generally were exactly what I hoped they would be: complicated, but with clear questions, and answers that were a pleasure to seek. That said, there are a few things I wish I could whisper to my past self, either right when I was starting this job, just as I was starting Hackbright, or a couple of years ago when I wrote my first lines of Python. Here’s a bit of advice to my past self, to anyone who’s considering this journey, and to anyone who’s still fairly new and would like a little reassurance.

1. Everything I heard about learning this is true (or: no, really, just pick a project).

If you want to learn programming, you do need to just pick a project and proceed. I really disliked this advice when I first heard it, because I am all about context, and I couldn’t imagine picking an appropriate challenge without knowing the limits and possibilities out there. And that’s a legitimate concern – it’s crucial to pick the right-sized problem, so far as complexity and the number of tools it will require, if you’re going to learn without getting so frustrated that you quit prematurely. Even so, it’s those raw edges, that unpredictable stuff, that gives you the real learning, that can be the most educational (and most satisfying) to wrap your brain around.

My real, substantial learning on this job began when I was put on a project, which didn’t happen immediately after I was hired. I had learned things before then, self-studying along in the office, but it lived strictly within the realm of the hypothetical (something I consider likelier a limitation of my own beginner state than anything else). Learning within the context of a project can be kind of like memorizing a poem by hearing every fifth word, and out of order and occasionally in a different language to boot. However, what you do learn will be practical and actionable, and – perhaps most valuable of all – will provide the context around what happened and what you need to do. And eventually, you’ll know a lot of it – and be able to intuit or sleuth out the rest.

My suggestion to you: it’s annoying how much it’s true, but I’d suggest just giving in (and finding a good advisor for picking and shaping your project, if you can). Find a practical problem in your own life and decide a way to start addressing it. If you get stuck, it’s a big, generous internet out there, and some of the people in it will even have right answers. 

Bonus suggestion: consider making a command line utility. It has a delightfully low barrier to entry and gives you a great chance to make something useful to you without worrying about deploying or front-end work. If you’re a Python kid like me, start by looking at argparse and then let your imagination run away with you. 

Bonus bonus suggestion: many programming communities now have Slack networks that are open to the public, if you request access. If you know you’re interested in a particular language and want someone to ask questions to, see if there’s an active Slack channel for your area of interest. The availability of DMs and the more regulated, curated nature of most Slack communities can make them friendlier to beginners.

2. Learning is a skill. Learning this is a different skill.

Computer science’s history is relatively short, but it’s some dense archeology, if you’re trying to wrap your head around even the most essential central stuff. Some people get to be immersed in it for four years before they’re thrust into the workplace; the rest of us get to pick up on useful commonality when we start playing with our third programming language. (Though people like Gayle Laakmann MacDowell have said that this is far from an insurmountable hindrance.) The good thing is that each new skill you learn will require slightly less origination and effort and will build slightly more on things you’ve already learned.

However, this growing knowledge will never reach one hundred percent, regardless of your background. If you plan on staying in this field, you have to learn to love at least a little constant disorientation. If you aren’t confused on the regular in your first couple of years in this field, you’re not trying hard enough.

My suggestion to you: learn to love feeling like your feet aren’t quite firmly planted beneath you, because it means you’re in the learning space. Disorientation means you’re surrounded entirely by new things to learn. Eat it up.

3. Any dregs of self-consciousness and admitting ignorance will either go out the window fast – or you will remain bad at this.

My company is largely remote four days a week, and I was, for a time, the only engineer in our central office. This meant that, if I had a problem and my manager wasn’t available, I had to go into a public Slack channel to seek help. This eased in time, mostly as I got to know my coworkers better. But until I got to that point, every question I asked felt like broadcasting my ignorance to the company, who only knew me as the inquisitive little Slack avatar. HEY LOOK AT ME HERE’S THE THING I DON’T KNOW OF THE HOUR.

That is, until I stopped caring because I understood that no one else cares. And beyond that, it’s as true here as in any other field that the best time to ask basic-ass questions is toward the beginning, when they naturally occur, before you start eroding the foundation you’re trying to build. 

My suggestion to you: breathe deep and get over it – or pretend to until it’s true. Admitting you don’t know something is a vital part of being good at this job, because there’s no room to bullshit. Any fudging you do will be revealed later, and most likely at a really annoying (and embarrassing) time.  

4. Useful experience is less about exhaustive knowledge and more about navigating new situations and tech.

Expertise can sometimes be demonstrated by knowing who wrote what language, what the most vital book is about a subject, or the history of the specific design decisions and needs that went into a framework. But this is surface trivia, and what’s most important (to me, so far) is context and the experience that provides it. It’s still the thing I crave most often, when I find myself in those disorienting moments where I don’t know the answer and am not even entirely certain of the right question.

It can be extra frustrating because I don’t just want to know how something works. I also want to know the situations where considering that thing as a solution on a project is appropriate, what would inform that recommendation, and what you heard about its past releases and future plans that might make everything terrible in six months.

I felt this basically constantly at the beginning and now, fourteen months in, I still feel this way pretty often. I choose to view it as still finding this field incredibly interesting. I can’t imagine what being bored or plateauing would look like in this job because there is always, always more stuff. And, after a while, you’ll have experienced enough of it that you’ll know better how to navigate the next big thing. 

My suggestion to you: hang in there, mostly. And just be willing to try things, volunteer for new projects, and get all of the experience you can – within reason.

5. My sense of curiosity is a valuable job qualification.

I have, in the past, annoyed lesser bosses by asking why. When I asked, I wasn’t questioning their judgment – or not usually, anyway. What I needed was to understand what went into a given decision, so that I could make my own decisions to support it appropriately. (Yes, it does make sense that I have user research in my background too.)

This quality is really useful in this job – in fact, in a well-functioning environment, I’d call it essential. It’s particularly so when you do consulting for clients, as my company does. Sometimes we serve them better not by doing exactly as they request but by asking why enough (and politely enough) to find out what it is they really want. From there, good work actually gets done.

My suggestion to you: your beginner enthusiasm and curiosity are valuable tools. When you don’t take anything for granted, you can notice things more seasoned engineers don’t. If something isn’t clear, ask about it (even if only privately to your boss) until it becomes clear.

6. Sometimes the tool is broken. Not you.

Early last year, I was doing some experimenting with AWS on my own at work, going between the command line and the web UI to launch instances, tailor and tweak them, and get used to the interaction between different aspects of the tool. But for a few weeks at the very beginning, things just didn’t work right. I’d follow a tutorial, enter a command, and – what even the hell? Trying to spin up an instance would fail. Security groups wouldn’t work right. And, worse still, I was so new and the failures were inconsistent enough that I couldn’t deduce any logic from what was happening. I was failing and didn’t feel like I was learning from it, one of the worst feelings. I rarely have reason to wonder if maybe I’ve been secretly stupid all along, but in that handful of weeks, I’d stop sometimes and wonder if engineering was finding some sad new quality of mine that had been hiding throughout my career.

Then another senior engineer got hired and had a little time before being put on a client. He found that our AWS account was old enough that it worked differently than more recently created ones do. He made a new account. Suddenly, tutorials made sense, and my results were predictable – including my errors. I was so relieved I had to stop and stare into space for a few minutes to absorb it all. AWS and I are friends now, despite our rocky start, but I would never have figured this out on my own.

My suggestion to you: sometimes the problem is between keyboard and chair, sure. But sometimes it is not. Ask questions, pair with someone, and make sure that someone who knows more than you witnesses your sticky moments sometimes. It’s ego-deflating, but it’s better than spending days or weeks flailing in some swamp that isn’t of your own making.

7. Timing is everything.

If you have even a semi-active sense of curiosity, you can spend endless amounts of time reading docs, essays, StackOverflow speculation, comments, comics, reviews by the competition, helpful blog posts, amusingly bitchy blog posts, and so many other things that may be very useful, completely useless, or – worst of all – approximately 29 percent useful. It’s that last one that can eat your afternoon. If you aren’t aware of this particular hazard, you can lose an hour or four much more easily than you might have ever suspected.

My suggestion to you: timebox that shit. And if you have access to someone more experienced than you, work out a relationship where you can come to them pretty regularly for reality checks and course corrections before you sail yourself deep into the ocean of chatty, chatty internet people. It’s ok to ask a more senior person to rule out some obvious stuff before you dig into researching your problem.

8. Unless the docs are shit, trust the docs.

(And if the docs are shit, should you really be using the thing it’s documenting at all?)

I realized recently (thanks to talking with one of my bosses; see the previous section), that I’d developed a habit I’ve nicknamed narrative research. I’d come to believe that the most efficient way to work through problems was to try to match my problem to someone else’s phrasing, find their solution on this or that third-party site, try to get that solution working to fix my problem, and then work backward to find out why what I had done worked, to learn a larger lesson from there.

Perhaps you’re already seeing the problem here.

If the tool you’re using requires the backassward methodology of someone in a completely different context than you to get it to work, it may be time to examine if you’re using the right tool – or, perhaps more likely, if you’re doing it right at all. You can stir your coffee with a screwdriver if you really want to, but there are better ways to use it. If you have a problem to solve, research just enough to find what library or whatever it is you need to use – and then use its own documentation. Don’t work off-label unless you really need to. Probably check with someone more experienced, if you really think this is a good idea.

My suggestion to you: there be dragons in Stack Overflow sometimes. Stay with primary resources as much as you can.

9. If you’re a person who does the caffeine thing, get your coffee game down.

I most often need one between three and four pm, just to perk my brain up to get through the rest of my day. A single Americano is a great way for me to address this. Recently, I messed up and overcaffeinated myself via the rookie mistake of using a bigger glass than usual for my cold brew. I spent the afternoon sweaty, with racing thoughts. Not a good look.

This is general life advice too, but I’ve found it more critical in this job than any other. It may seem surface, and maybe it is surface, but having your biological needs in check will let you do better at this.

My suggestion to you: know thyself.

10. Don’t be a hero when you’re sick.

This is especially important for me and my consulting colleagues who have a vested interest in quality billable hours, but: if you’re sick, be sick. Don’t soldier through. (And not just because of the obvious part about not being a disease vector. Seriously, stay off my BART if you’re ailing and have sick time to use.) If you feel like shit, you’re not going to be able to brain, and this work requires a functional brain more than any other job I’ve had. The others could be difficult too (especially the UX consulting gig I had just before I went to engineering school), but it’s just… different. Pack a snack, sleep enough, and pay attention when you’re sick.

My suggestion to you: be an adult and be honest with yourself. Sleep enough, eat enough, and stay home with pho from Seamless if you’re under the weather. Treat yourself like you’re parenting a toddler – you know, honest assessments. Sometimes you just need a snack; sometimes you need to stay the hell in bed.

11. And, finally: decency counts.

This is an industry riddled with social fuckery, and even people who found it worthwhile to stick it out usually have at least a couple really vile stories of colleagues and managers acting like total assholes. I work in a magical unicorner of the industry that’s largely free of that, but – get this – I still get points just for being housebroken and friendly enough that it’s pleasant to share space with me. It still seems to be considered remarkable in this industry (though it’s a requirement to work at my company). Can you treat a troublesome team with human decency? Can you be polite and keep it together even when you’re having a bad feeling and not getting your way? Do you have a regular life, and can you make nice chit-chat about it without it being a big thing? Congratulations: you have an important skill.

Beyond that, social stuff in tech is just different than it is in other industries. I’ve always been lucky enough to have coworkers I wanted to be friends with too, but there’s a certain all-banding-together kind of feeling in tech that I haven’t seen anywhere else. In some companies, it’s a natural side effect of putting a bunch of 22-to-29-year-olds with a shared predilection for alcohol in the same space for 60-plus hours a week. But even then, it has a function – when stuff gets hard, that empathy and caring and shared knowledge comes together, and everything functions better.

My suggestion to you: be cool, honey bunny. And, even if you have limited social energy (I certainly do), try to conserve some of it to spend time with your coworkers once every week or two. A lot of people are lovely, and the stuff about being a good member of a team is easier if you’ve taken a real interest in the people around you.

There you go, new engineer. There you go, Breanne of a year or two ago. And here are a few more resources that I’ve found really useful in the last year. I didn’t even write all of them myself.

  • How to edit your PATH variable (and what PATH is): I had the hardest time getting an answer to this, which was tough when I was already learning a lot about how a computer works when you’re not just using it to dick around on the internet. So I pestered my coworkers for answers until it felt coherent and wrote it down. I hope it helps you too.
  • 7 Things I Wish I Knew Before Starting at a Developer Bootcamp: my friend and coworker Emily Chen wrote this, and I really wish I could teleport it back to myself in spring 2015. Why this isn’t a prereq for every immersive programming school, I do not understand.
  • The rad illustrations of Julia Evans: always thorough and yet always approaching subjects from a unique angle, her illustrations are such a nice companion for whatever you’re learning.
  • And, just, you know what? Wikipedia is the shit for computer science stuff. Surprise! There’s a lot of legit documentation out there (ahem, man pages, ahem), but Wikipedia is so often a great place to start, and seeing unfamiliar stuff laid out in a familiar format can be really helpful if you’re stumped.

Python with Flask and PostgreSQL: “Is the server running on host “localhost” (127.0.0.1) and accepting TCP/IP connections on port 5432?”

My beautiful errors when I encountered a certain server error with PostgreSQL and Flask

This one goes out to the new people who are, as I described myself a few minutes ago, “still building context.”

This error is not this. This error is not that.  This is error is that you, perhaps like me, restarted your system recently and didn’t restart Postgres.app.

“I can’t reach the server,” it says. Maybe you, like me, will get stuck on the port thing, thinking that server.py is having some new and terribly exotic error. Server.py is running. What is its problem? It’s RIGHT THERE.

No.

Restart your database server. (Or, y’know, start it.)

Then change your preferences so PostgreSQL starts after login for the duration of your project.

You’re welcome.

This blog post is brought to you by me wishing that I’d found the perfect, straightforward answer to this simple-ass question. Port 5432: not a part of server.py. No, it is Postgres. Just Postgres.

Now you know. Get it.

For Google fu, here’s the relevant text of the screencap above:

OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused Is the server running on host “localhost” (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Connection refused Is the server running on host “localhost” (fe80::1) and accepting TCP/IP connections on port 5432? could not connect to server: Connection refused Is the server running on host “localhost” (127.0.0.1) and accepting TCP/IP connections on port 5432?