More Tribal

  • The Tribal Pizza Website
    Now that you've looked behind the curtain, come see what's on stage!

Enter your email address:

Delivered by FeedBurner

Technology

September 17, 2007

How do we secure your password you ask?

Actually, you didn't ask. But, we think you should have. Better yet, we think you shouldn't have to. Expect this information to migrate on to the main site. We feel as a holder of your account and personal information we have a responsibility to inform you on how we manage your password and personal information. We feel every website you interact with should do the same.

Found a fairly timely post on digg this morning regarding this topic -- You're Probably Storing Passwords Incorrectly. It's timely because I was planning on writing about this topic today. Glad to see other people are concerned about this. This is an interesting topic; most websites (even several of the more famous) do this wrong). Jay and I put a bit of thought into this upfront. We made a few conscious decisions regarding management of passwords and personal information we thought was best for the consumer. Namely:

  1. We would not store passwords. Rather, we would store salted hashes. This brings up one minor inconvenience -- if you loose your password we generate you a new random one. We CANNOT recover your password. At the same time, outside of a brute force attack neither can someone who snags our customer database. We use a SHA-512 HASH along with a randomly generated 8 byte salt for each password stored. One thing we could improve is increasing the size of the salt.
  2. We would not have a pre-canned set of security questions for password reminders or reset. We can't recover your password anyways. Instead we provide you a reminder -- you can put what you want there. Doesn't matter to us. Lot's of folks put a hint or the word 'standard' to indicate this is the one they normally use. One thing we feel strongly about is canned questions are inherently insecure and a reminder can be secure if you choose it to be.
  3. We did not want to put password strength checks into the password requirements. Oh no! You guys don't care about my security! Actually, we do. Those that use good strong passwords will continue to use good strong passwords. Those that don't wont. Rather than force you to conform to a set of rules we think is good we let you choose. I think it is arrogant to assume someone who can't remember a complicated password will if you force them to for their own good. They will simply write it down somewhere! Now what did you achieve? This one is near and dear to my heart. I used to work as a sysadmin for the University of North Texas. I worked for this great old tinkerer named Jerry. Jerry maintained the servers and the computers for the Department of Engineering. One day I got the bright idea to put in a more secure admin password. Shortly I realized my mistake. Jerry was a smart guy, but, older and just couldn't remember the password I created so he wrote it down on a sticky. All I did was lower the security of the system!
  4. When we start accepting orders we are going to provide you the option of storing your credit card information for quick checkout. When we do this, we will encrypt the information using your password to synthesize a key. This means that we will ask you for your password one more time before processing a speed order -- remember we don't have it! If our database is stolen then each credit card number stored must be brute forced. The difficulty of this act will depend on each user's password. Yes, this means if you reset your password we will discard the encrypted credit card information because it can no longer be recovered.

One weakness in our current system is that during password reset your new password is sent to your email. As we all know, depending on the route from us to your inbox that email may be read by snoopers along the way. There aren't many great solutions to this problem that do not incur lots of verification headaches for you and us. Again, we don't feel too terrible about this because if you did store any super sensitive information with us, it would have been destroyed by the password recovery. This is an area we will continue to think about and refine. Any suggestions out there are welcome.

We feel these choices provide a good compromise between securing your personal data and providing a good customer experience. We also feel that websites should be more forthcoming in how the manage and secure your accounts and personal information. Hiding this information only helps attacker and would be malfeasants.

What do you think of our choices?

September 16, 2007

Dealing With The Database - The Great Impedance Mismatch (Part I)

First, a minor confession, I dislike loathe databases. The only thing I may loathe more are the self-appointed high-priests of databases, DBA's. However, They are a necessary evil. Invariably, most software solutions need one, so I begrudgingly accept its role. My major complaint is that the industrial solutions that exist today are all some form of Relational Database Management System (RDMS). Working with them always is a hassle. The software I write has nice little object abstractions for the entities I deal with it – it's great. I don’t worry much about how they do what they do – they just do it. That is until I must bridge the great impedance mismatch to get them in and out of the RDMS.

There are many solutions to this problem – most of which I am continually disappointed with. There are several Object-To-Relational Mapping (ORM) solutions out there; most of which I despise. Why? Well, they ask me to know too much about the database (remember I loathe them???). I don’t want to design stored procedures, I don’t want to design tables, and I don’t want to map the two. I want to build objects! 

Why must I: 

  • Maintain data layout information in two places?
  • Know some less than conformant version of SQL syntax?
  • Deal with a mess of SQL scripts as I adjust the definition of objects over time?

In my previous commercial existence, I and some very talented folks have waded right into this problem. The first time we tackled the problem, it was to provide an RDMS like view of network data. As things went forward, we realized we wanted to address this problem in such away as the backing store did not matter. In other words, the objects we requested information from could be backed up by a database, network calls, excel spreadsheets, etc. You get the idea! 

Before you all start posting comments, yes I have heard of ODBC, ADO.NET, WMI, CSLA, and Hibernate. Hold your horses. Each of these doesn’t really help solve the problem I want solved. I DON”T WANT TO DEAL WITH THE DATABASE. 

Further, when querying I am a huge fan of Query by Example (QBE). Let me show you an object and you give me back a list of them that look like it.

Here is how this works (lights, camera, pseudo-code): 

Formula exemplar = new Formula();

IStore store = ServiceFactory.Instance.Retrieve<IStore,Formula>();

exemplar.Email = ‘mwebb@tribalpizza.com’; 

Console.WriteLine (“My formulas”); 

foreach (Formula f in store.Retrieve (exemplar))
{

Console.WriteLine (f.Display);
}

Yes, this is how our current system works. Short, sweet, and to the point. 

In dealing with this problem, I want to work with three real abstractions: 

  • An entity
  • An entity’s definition
  • A store

An entity is just that -- well let’s say something like a Pizza Formula. I want to describe its properties, their constraints, relevant data-types, and be done. We’ll call this description an entity’s definition. 

A store is a place to store and retrieve entities from.

Here is how I want life to work: 

  1. I describe an entity declaratively
  2. A code generator creates me a magic wrapper for ease of dealing with the entity. This is not entirely necessary but damn handy. The system needs to be able to retrieve and operate on entities for which these wrappers don’t exist though!
  3. A store is selected based on an implementation of the service factory and the type of identity. This gives me great flexibility in changing out backing store as well as potentially selecting the type (and characteristics) of the backing store based on entity.
  4. A store must be able to read an entities’ definition and create the necessary backing store for the entity. Period! I don’t want to help it. Read the definition and create the store. I’m not creating your SQL scripts, got it.
  5. A store must be able to read an entity’s definition and realize that a newer description exists. The store must be able to take reasonable actions to upgrade the backing store to realize these changes. When I say reasonable, I say the store should be smart enough to handle the additions of columns. Changing the data-type and/or deleting of columns may be beyond the capability of the store. I generally try to avoid these operations anyways.
  6. A store must be able to perform relevant read, delete, and update operations.
  7. I want to be able to access existing data without having the original data definitions. How? Well, easy, the backing store is also responsible for keeping track of the data definitions used to create objects. Wow! This has huge implications. More to come on this in the future. 

Now, I know I loose some things: 

  1. I may not be able to eeck out every micro-second of performance that a perfectly tuned SQL script could offer. However, I intend to deal with this problem another way. The selection of which store to use is done by requesting a store from a service factory based on entity. This allows me to *tune* up specialized stores for performance critical entities that have special characteristics. I shouldn’t need to do this much, but, I have a back door if needed.
  2. I am accepting some amount of lowest common denominator in backing store capabilities. Again, if this is a challenge see my solution to the problem above. 

I’ve made some pretty good progress on a solution that works for us. This is the first part in my series of explaining the design philosophy and its inner workings. Eventually, we will be sharing an open source solution to this problem. 

What are your thoughts on the great impedance mismatch and my approach to the problem?


July 29, 2007

Software Isn't Legos! It's IKEA Furniture.

MynameisallenAs often happens in a startup, I found myself at IKEA yesterday.  We needed a place to put our coffee pot and microwave, which is the extent of the kitchen equipment that we have right now.  I picked up a Gehrfleugurfluggen chest that seemed to fit the bill and for $80 I was out the door. After I got back to the office and started putting it together, it struck me as a good analogy to software development -- far superior to the common "components are like Lego bricks" analogy that I read so frequently.

Let's start with the problems I see in the Lego analogy:

  • With Legos, pieces fit together in a consistent fashion.  Outside of using Super Glue, they'll always connect the same way, even if you're building different designs.
  • Legos are HIGHLY standardized.  Sure, you can add the space pieces and castle pieces and Star Wars pieces, but those are more like design elements than core components.  When the media trots out the analogy, they're talking about the standard little blocks.
  • Hand 2 people identical sets of Legos and identical instructions and you'll get identical results.  Does that sound ANYTHING like software development to you?

Okay, here's why I think that IKEA furniture is a much more fitting analogy:

  • They give you all the parts and instructions, but so many times you find yourself undoing what you just did in order to do it the right way.  The pieces may be backwards, upside down, or just plain wrong, yet they still seemed right at the time.
  • IKEA pieces are familiar in style and function, but they can be wildly inconsistent.  While putting together the Gehrfleugurfluggen, I put the little cam wedgies in to hold the sides on and then they all fell out.  It turns out that there were 2 sizes of cam wedgies, one for sides and one for drawers.  They have you put the sides on first.  There were 4 side wedgies and 12 door wedgies which made the chance of grabbing the door wedgies much higher.  Not only that, but the side wedgies are bigger which meant that the door wedgies would "fit" in the side holes, further leading me down the false path.  Sound like software to you?
  • Hand 2 people the same IKEA pieces with the same Wordless Workshop style instructions and you'll get 2 different pieces.  Assembler #1 will use all the nails to attach the back piece.  Assembler #2 will use about half the bag.  Assembler #1 will actually attach the little safety strap;  Assembler #2 . . . not so much.  Assembler #1 will finish in about half the time having put everything together correctly on the first attempt.  Assembler #2 will have scratches, dents, and loose pieces from having put things on backwards and then "fixing" it.

Having played with Legos, assembled IKEA furniture, and written software throughout my life I can attest to the latter analogy being much closer to the current state of development.  If you have a better analogy, feel free to post in the comments.

P.S. Assembler #1 uses emacs . . . Assembler #2 uses vi.

July 26, 2007

The Birth of the Carputer

(click on images for larger version -- photos courtesy of Ecor Rouge Photography)

Carputer1 The Tribal Pizza concept started in mid-2003 with 4 words: "GPS to deliver pizza".  At the time I was Chief Technology Officer of DuClaw Brewing Company, the #36 brewery in the world, according to ratebeer.com.  I spent a lot of time writing software to manage restaurant operations and one day it occurred to me that pizza delivery could utilize more technology than any other type of restaurant.

Now it's 4 years later and Tribal Pizza lives.  The heart of our delivery platform is our site.  The brains is a computer that we call Pizza Box in each unit.  The arms and legs, however, are The Carputer.

The Carputer is responsible for the following tasks:

  • Routing deliveries and giving turn-by-turn directions.
  • Updating the vehicle's location and estimated time to delivery on the main site in near real-time
  • Monitoring vehicle performance, such as MPG, driving characteristics, and maintenance needs
  • Presenting special delivery instructions to the driver
  • Rocking out with XM radio

Carputer2 The photo to the right shows the Carputer in assembled form during development.  You can see from the Blue Screen of Life that we're running Windows.  We use XP Embedded since we have a lot of .NET development experience.  The fingerprints on the screen attest to the fact that it's a touchscreen LCD. Carputer5 Most of the parts were purchased from mp3car.com.  The XM Universal Tuner in the front was purchased at Best Buy and the wiring and power supply used for development were purchased at Radio Shack.

As it stands, the Carputer boots, runs our custom .NET application, and receives GPS data.  In other words, it's alive but not particularly useful yet.  As we add functionality, we'll be posting not only what's been accomplished, but some code and downloadable components.  We keep telling ourselves that a lot of what we need should already exist, so we decided to give away some of the pieces, such as our .NET XM controller.   Carputer3

To the right you can see all the parts that are going into the system and below is a close-up of the daughter-board that Carputer4 holds the hard drive.  If you're going to put a computer into a car, play it safe and use a laptop drive.  They're design to withstand more movement than your average desktop drive.

Any questions about the hows, whys, why-nots, etc. can either be posted in the comments or sent directly to me at jgrieves@tribalpizza.com