The physical aspects of OpenStreetMap's data are contained within the data model and primitives, but it's the tagging of each primitive that tells you what all the features are, and where the real power of the model lies. The data primitives have tags added to them that tell you what real-world features they represent, and from that you can render a map, produce a routing mesh, or build some other application.
A tag is a simple key-value pair. Any primitive can have an arbitrary number of tags attached to it. The keys and values are simple strings, and can contain any valid Unicode characters upto a 255 character limit. The OpenStreetMap server currently uses the UTF-8 encoding scheme.
That is the entire technical specification for tagging in OpenStreetMap. The API itself doesn't enforce any more rules on tags than the ones just mentioned. Instead, what gets put in tags is decided by the OpenStreetMap community, through custom, discussion, and consensus. There are already a huge number...