But after a bit more looking I saw that Apple invented their own protocol, called NAT-PMP, and the Airports only support that. This is normally pretty annoying, but UPnP is widely reported as bloated (protocol docs mention SOAP among others), and Apple's protocol is hella simple -- send a 12-byte UDP packet to the NAT box and it opens up the port.
So here's a trivial Ruby library for NAT-PMP. I haven't implemented the backoff requirements of the protocol (since UDP is unreliable, they ask you to retry with exponentially increasing timeouts), but it gets the job done. (The Avahi people are already working on integrating support for NAT-PMP, and they'll probably do it all Right.) There's some example code at the bottom of the module.
PS: If you try this and get a "not authorized" error, you have to turn on NAT-PMP in your Airport config. Go to the first page of the settings in the Airport Admin tool and click the "Base Station Config..." button.