How to do a spatial join in PostGIS that returns on the minimum value of point intersecting polygon?

First use a window function to get the ordered rank of the dem_points. In a second step filter the dem_point with the lowest dn by the rank.

SELECT osm_id, gid, dn
FROM   (
         SELECT b.osm_id, p.gid, p.dn,
                row_number() OVER (PARTITION BY osm_id order by dn) as rank
         FROM   buffer b, dem_points p
         WHERE  ST_Within(p.geom, b.geom) 
       ) joined
WHERE  rank = 1

You need to group the points per buffer geom, then find the min(dn) for each buffer geom, and finally join it back to the original to get the point gid. Try something like this (using WITH syntax to make it slightly easier to follow):

WITH foo AS (
  SELECT b.osm_id, p.gid, p.dn
  FROM buffer b, dem_points p
  WHERE ST_Within(p.geom, b.geom)
), bar AS (
  SELECT osm_id, min(dn) as dn FROM foo
  GROUP BY osm_id
)
SELECT bar.osm_id, foo.gid, bar.dn 
FROM bar JOIN foo ON foo.osm_id=bar.osm_id AND foo.dn=bar.dn

Note that another way to do this is to use PostgreSQL's HAVING clause but I think that's more difficult to follow.