Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

Origin(al) Sins

Video is now up from a talk I gave in October at OWASP's AppSec USA conference -- something of a departure from my usual speil:

Origin(al) Sins - Alex Russell from OWASP AppSec USA

I made some pretty glaring errors in the talk: you can't combine sandboxing with seamlessness for cross-origin content. It's something I'm hoping we can improve on in the browsers/specs, but it's not the current state of play. I also failed to mention that CSP is Mozilla's brain-child and they deserve huge credit for pushing it down the field. Similarly, I failed to mention that IE 10's CSP support is actually quite shite, supporting only the sandbox directive. Lastly, my objections to the OCAP worldview may have been oblique so, before the flames arrive in the comments, let me try again:

I think that you'll always end up with some variant of "object capabilities", if only through wrapper objects that hide protocol details. The OCAP world calls these "membranes" for particularly high-fidelity versions of this. When you have a word for it, it's probably common. Vending objects that represent capabilities is natural at some level, but I strongly resist the urge to take the pun too far. Don't get me wrong, I'm a huge fan of capabilities as the model for building apps that have real security by default; and I hope their pervasive use combined with more restrictive, separated execution contexts creates the world we all want to be in. My only quibble is on the developer ergonomics front. OCAP encourages the (perhaps naive) programmer to build many things inside the same "vat" (heap, context, whatever), leading to brittleness whereas protocols and true sandboxing can create secure boundaries that, importantly, look like boundaries. Systems that provide big "this is a security boundary!" disclaimers on their APIs while making it hard to screw them up stand a better chance of weathering the storms of human imperfection. Can you do OCAP right? Sure, it's possible, but as I argue in the talk, betting on humans to do the right thing is eventually and inevitably a loser. So I favor large, knobby interfaces over which you can send messages and no more. Wrap 'em up with an RPC But design a protocol with side-effects that are straight-forward to reason about on both sides -- not an object which can be easily intertwined with many others in a dense graph -- and you've got my vote. I'm even in favor of building those protocols and then wrapping them with easier-to-use APIs (call it "CAP->O", if you will), but eliding the step of a large boundary over which you can only send data, and making it relatively hard to cross? Nah, I'll be over here with the easy-to-reason about solutions that don't make my small-ish brain melt, thanks.

Also, I wasn't sure to what extent Doug was joking about "incompetent" programmers in his talk, so our disagreements may not be what they seem. Caveat emptor.

Thanks to Jeremiah and the other organizers for taking a risk and inviting someone who's been out of the security space for so long to give a talk. I promise to them that should they be so foolish in the future, I'll be sure to duck out and get one of my betters on the Chrome Security Team to stand in instead ;-)

Layers of Confusion

I missed a Plus post by Ian Hickson back from August but I saw it today through the magic of the twitters. It contains quite a lot to quibble about, but I want to home in on something he wrote in the comments in response to Will Sargent, RE: one of my posts on layering in the platform:

...I don't really share his vision. I think JS is an important part of the Web, but I don't see it as any more core to the Web than CSS, HTML, the DOM APIs, HTTP, etc. Most of the proposals I've seen to take JS and build a platform on it tend to fall down on #3, #4, and #5. In particular, I think fundamentally #3 and #4 basically force the platform to have a declarative part (the declarative XAML part of .NET is how it managed to address #4, for instance, and the declarative design of XHTML2 and RDF are how they manage to address #3). That doesn't have to mean that the code part is a secondary part, though. I think the Web has reached a point where you can think of the DOM as the core, with JS and the HTML syntax layered atop that (much like how in .NET there's objects that can be represented in XAML or generated from C#), which puts the JS part on par with the HTML part in terms of importance to the platform.

This is either me not articulating my "vision" clearly, Hixie mis-understanding my point(s), or some combination thereof. So I'll try again in 4 paragraphs:

I make no claims about the relative importance of HTML, CSS, JS, DOM or any of the rest. It honestly feels silly to talk about the platform that way. I argue something very, very different: HTML, DOM, and (to a lesser extent) CSS should all conceptually bottom out at JS. I'm not saying "go write a browser in JS"...that's also non-sequitur. JS must, of course, appeal in turn to C/C++ so a "browser written in JS" would need privileged APIs provided by C/C++ or something lower level.

What I'm saying is something very direct: there's no other ubiquitous programming language for the web. JS is the only game in town. As a result, when we describe imperative behavior in prose (as the HTML5 spec does) that behavior could, in theory, be implemented in JS (or some sub/super-set). Since HTML, DOM, and CSS aren't Turing-complete, they naturally belong at a "higher level" in the web platform stack.

Now, all of this sounds dangerously academic and perhaps nuts...but consider that we have to expose APIs for nearly all of this stuff. Whenever we add something to HTML, CSS, etc., it always comes with some sort of API. Now, that could be a good API, or it could be an obtuse turn around the parser after some terrible string concatenation.

I'm claiming that you get better APIs when you design your imperative explanation of the declarative stuff -- which you MUST do for specs to be sane -- in JS. This means designing new APIs to help you accomplish the task at hand as you go. Doing it that way ends you up with the types, APIs, and security boundaries you're going to need in the end anyway. Doing it the other way, patching crap onto the side later without explaining how the declarative stuff "works", just leads to the pain and constant need for case-by-case revision that we see in today's web APIs.

That's the whole argument in 4 'grafs. It's subtle, but I hope not terribly controversial. Importantly, nothing about it demands giving up on any of Hixie's 5 arguments. He can keep 'em all and still get a well-layered platform. We've got enough examples of doing it wrong under our belt to see how painful the badly-layered web is today. We can end this insanity -- not by claiming that any part of the platform is "more important" -- by explaining the platform in layers, higher levels in terms of the lower levels.

Bits and Remainders

I've been working on an epically-long blog post on the Offline problem for something like two months now and it's still not done. That's not so much to tease as warn; Frances thinks I should post it in installments. It's that long.

As a result of that ever-growing design/analysis/writing hairball, I haven't blogged when I might have. Videos of some of my recent talks are now up, including my Fronteers closing talk:

Alex Russell | The Web Platform & the Process of Progress | Fronteers 2012 from Fronteers

Special thanks to Peter and the Fronteers volunteers for managing to find a pink boozy cake (a culinary revelation!), simultaneously meeting my only (joke) demand as a speaker and trolling me in person. WELL PLAYED.

Also, give the rest of the excellent talks a gander over on Vimeo . Personal favorites of mine include the ever-brillaint Phil Hawksworth, Marcin Wichary's stunning Doodles talk, Lea Verou, and Rebecca Murphey....actually, there were too many to list. Seriously, go check it out.

I also recently spoke at the London Ajax User's Group, and video is also available (but not embeddable). Apologies for both videos including a lot of me rambling. I need to get better at this whole "public speaking" thing.

On a related note, FFJS was once again brilliant. Best one day conference going this side of the world, hands down. Congrats to Julie and Remy on a stonkingly good day.

Election Season

So election season is upon us -- no, not that one -- elections for the W3C's Technical Architecture Group (TAG). You might be thinking to yourself "self, I didn't know the W3C had such a very strange...I wonder what it does." Also, you might be wondering why I'd bother to write about a perfunctory process related to a group whose deliverables you have probably never encountered in the wild and are fantastically unlikely to.

The answer is that I'm now in the running for one of the TAG's 4 open seats. At last week's TPAC I was talked talked myself into running. Google has nominated me, so we're off to the proverbial races. Given the number of condolences I've received since deciding to run, you might wonder why I'd do such at thing at all; particularly since the general consensus is that the TAG's impact is somewhere between "mostly harmless" and "harmless". I've never heard it described as "valuable" or "productive" in its modern incarnation, so why run? Could it be for the warmth of human contact that a weekly conference call could provide? A deep-seated but as yet unfulfilled desire to weigh in on what really irks me about how people use HTTP? Indeed not.

I'm running to try to turn the TAG into an organization that has something to say about the important problems facing devs building apps today; particularly how new specs either address or exacerbate those challenges.

Notionally that's what the TAG does now; review specs in development and provide feedback. If you look at the current work items, however, there's nothing about JavaScript. There's similarly little on DOM or the sorry state of API design at the W3C and how it is enabled by WebIDL and a broad cultural ignorance of JS. The TAG could provide advice on API design to WGs, how to think about creating a well layered platform, and how to keep webdevs in mind at all times.

State management gets a lengthy exposition that doesn't do much to uncover the challenges in designing apps that need to keep and manage state, synchronize that state in local data models, and map state onto URLs. Its a hard problem that most JS-driven apps struggle with and the TAG has no view beyond motherhood, apple pie, and pushState(). It can do better.

For webdevs, the TAG is a natural ally -- it carries the weight of the W3Cs reputation in ways that vendor-motivated WGs don't. It can be an advocate for building things well to reluctant managers and organizations, helping you make the "environmentalist" argument; "the web is for everyone, why are you making it bad?" It can also be a go-between for agitated webdevs and the WGs, a voice of reason and patient explanation.

As a talking shop, the TAG can never be expected to have power over implementations or webdevs, but it can be opinionated. It can take a stand on behalf of webdevs and call out huge problems in specs, missing work items for WGs, and build bridges to the framework authors that are doing the heavy lifting when the browsers don't. It can also build bridges to other standards bodies that specify hugely important parts of the web platform, bringing a webdev perspective to bear.

I have worked inside a browser, represented Google at TC39, and have built large apps and frameworks on the web stack. I have seen firsthand how the TAG isn't doing this important work of building bridges and jawboning on behalf of web developers. And I plan to fix it, if elected.

If you work at a company that is a member of the W3C, I hope to get your AC rep's vote. If not, I would still love your support in letting AC reps from the Member organizations know that you support the goal of turning the TAG into an advocacy organization for the interests of webdevs.

If you're particularly interested in this problem, I'd love your help -- I'm looking for reformist-minded candidates to join me in running for the TAG. If you don't have a sponsoring or nominating organization, send me mail or a tweet.

Voting nitty-gritty, largely cribbed from Ian Jacob's mail to a Members-only W3C mailing list:

Inadmissible Arguments

I spend a lot of time working in, on, and around web standards. As a part of this work, several bogus perspectives are continuously deployed to defend preferred solutions. I hereby call bullshit on the following memetic constructs:

"That's just a browser caching problem."

Look for this to be deployed along standards-wonk classics such as "our job should just be to provide low-level primitives", "we don't know enough to solve this", and "people will just write tiny libraries to provide that".

"It's a caching problem" is a common refrain of those who don't build apps and aren't judged on their latency. And it's transparently bullshit in the web context. It relies on you forgetting -- for just that split second while it sounds possible to duck the work at hand -- that we're talking about a platform whose primary use-case is sending content across a narrow, high-latency pipe. If you work in web standards and don't acknowledge this constraint, you're a menace to others.

Recent history alone should be enough to invalidate the caching argument; remember Applets? Yeah, Java had lots of problems on the client side, but what you saw with client-side Java were the assumptions of server-side engineers (who get to control things like their deployment VM versions, their hardware and spindle speeds, etc.) imported to distributed code environments where you weren't pulling from a fast local disk in those critical moments when you first introduced your site/app/whatever to the users. Instead, you saw the piles upon piles of JARs that get created when you assume that that next byte is nearly free, that disk is only 10ms away, and that cold startups are the rare case. It worked out predictably and Java-like systems succeed on the client when their cultural assumptions do align with deployment constraints -- Android and iOS are great examples. Their mediated install processes see to it.

Back out here on the wolly web, caching is something that's under user control. It must be for privacy reasons, and we know from long experience that users clear their caches. The "cache" they can't clear is the baseline set of functionality the platform provides -- i.e., the built in stuff on all runtimes developer cares about...which is what specs can effect (obliquely and with some delay).

By the time you're having a serious discussion about adding a thing to a spec among participants who aren't obvious bozos, you can bet your sweet ass that the reason it was brought up in the first place is a clear and obvious replication of effort among existing users bordering on the ubiquitous -- often in libraries they use. Saying that someone can write a library rises no higher than mere truism, and saying that a standards body shouldn't provide some part of the common features found among those existing libraries because caching will make the cost of those libraries moot is ignorance or standards-jujitsu in an attempt to get a particular proposal shelved for some other reason.

As bad as the above is, consider the (historically prevalent) use of this argument regarding "why we don't need no stinking" markup features -- just "fix" browser caching and "give me a low-level thing and I'll build [rounded-corners, gradients, new layout mechanisms, CSS3d xforms, etc.] myself". The subtle bias towards JavaScript and away from a declarative web is one of the worst, most insidious biases of the already enfranchised upper-class of JavaScript-savvy web developers, perpetuating a two-tier web in which "real engineers" can do better every year but wherein those same expressiveness and performance gains aren't transmitted to folks without CS degrees (yes, I'm looking straight at you, WebGL). You almost want to give it to them, though, so they'll finally come to terms with how wrong they really are about the ability for caching to be "fixed".

We've spent a decade on this -- remember that we're all using CDNs, pulling our JS libraries from edge-cached servers with stable URLs for optimal LRU behavior, running minifiers, setting far-forward expires, etc. And that's just what webdevs are doing: meanwhile browser vendors have been working day and night to increase the sizes of caches, ensure full caches where possible, and implement sometimes crazy specs that promise to help. It's not for lack of trying, but we still don't collectively know how to "fix" caching.

Think libraries are free? Show me how you'll make 'em free and I'll start taking you seriously. Until then, bozo bit flipped.

"It should have exactly the same API as library X"

Similar arguments include "it must be pollyfillable", etc.

Why is this bullshit? Not because it represents an aversion to being caught in an implementation/deployment dead zone -- that's a serious concern. Nobody wants a better world dangling out there just beyond reach, waiting for Vendor X to pick it up and implement or for Version Y of Old Browser to die so that 90% of your clients can acces the feature. That's where libraries provide great value and will continue to, no matter what the eventual feature looks like. Remember, the dominant libraries in use by developers don't have Firefox, Chrome, IE, and Opera-specific versions that you serve up based on client. The platonic ideal is 180-degrees in the other direction: one code base, feature detection, polyfills, progressive enhancement -- basically anything within (and often well outside of) reason to keep from serving differential content. So your library is going to have all those versions anyway until all of your clients have the new-spec version. Optimizing based on existing API design because "now we can polyfill it without extra effort!" misunderstands both the role of spec designers and of libraries and serves users very poorly indeed.

Where this argument becomes truly inadmissible, though, is when it seeks to define the problem to be "what our API already does". Turns out that the language you can design features with when all you have is JavaScript and HTML/CSS patterns is...well...the JS, HTML, and CSS you have today. Powerful yes. Expressive? Hrm. If your job, however, is to evolve an integrated platform, taking on a constraint predicated on the current form of your systems is nuts. There are some hard constraints like that (backwards compatibility), but adopting some form of hack as the "blessed" way of doing something without looking around and going "how can we do this better given that we have more powerful and expressive language to solve the problem with?" is nothing but lost opportunity.

Yes, a standards group might look around and go "nope, we can't do better than that polyfill/library" and adopt the solution wholesale. That's not a bad thing. What is bad, though, is advocacy about far-future solutions to current problems based solely on the idea that some library totally nailed it and we shouldn't be asking for anything more -- e.g.: Microdata cribbed from RDFa and Microformats when what you really wanted was Web Components. Rote recital of existing practice is predictably weak sauce that robs the platform of its generative spark. We should all be hoping for enhancements that make the future web stronger than today's, and you only find those opportunities by taking off the blinders and giving yourself free reign to do things that libraries, polyfills, and hack just can't.

What to do about the developers and users caught in the crossfire? Well, we can advocate for degradable, polyfill-friendly designs, but there are limits to that. The most hopeful, powerful way to make the pain disappear is to ensure that more of our users year-over-year are on browsers/platforms that auto-update and won't ever be structurally left-behind again. And yes, that's something that every web developer should be working towards; prompting users to update to current-version auto-upgrading -- "evergreen", if you will -- browsers. Remember: you get the web you ask your users for.

"Just tell us the use cases"

This is the one I'm most sick of hearing from the mouths of standards wonks and authors. What they're trying to say is some well-meaning combination of:

What it often winds up doing, however, is serving as a way for a standards body or author to shut up unproductive folks; folks who aren't willing to do the work of helping them come to enlightenment about the architecture of the current solution, the constraints it was built under, and the deficiencies it leaves you with. Or it can be used to avoid that process entirely -- which is where we're getting towards bullshit territory. Taken to the extreme (and it too often is) the "use-cases, not details" approach infantilizes standards body participants, setting a bar too high for the folks who are crying out for help and setting the bar too low for the standards body because, inevitably, the tortured text of the "use cases" is an over-terse substitue for a process, a way of building, and an architectural approach. Use-cases (as you see them for HTML and CSS in particular) become architecture-free statements, no more informative than a line plucked at random from Henry V. Suggestive, yes. Useful? Nope. The very idea of building standards without a shared concept of architecture is bogus, and standards participants need to stop hiding behind this language. If you don't understand something, say so. If many people work hard to explain it and can't, ask for a sample application or snippet to hack on so you can do a mind-meld with their code and can ask questions about it in context.

Yes, having the use-cases matters, but nobody should be allowed to pretend that they're a substitue for understanding the challenges of an architecture.

While I've only covered a few of the very worst spec-building tropes, it's by no means the end of the rhetorical shit list. Perhaps this will be a continuing series -- although I'm sure this post will offend enough folks to make me think twice about it. If we put an end to just these, though, a lot of good could be accomplished. Here's to hoping.

Older Posts

Newer Posts