This works for us:
1. User must exist in the msdb database.
2. User requires one of 3 roles in msdb database: SQLAgentOperator, SQLAgentReader, SQLAgentUser role.
3. Make sure the principals are mapped to the proxy.
The one "gotcha": Never let a non-admin explicity name a job owner as only admins have the permission to do that.
If you are interested, we wrap the actions in a stored procedure that does the following:
1. Dynamically creates a new job name
2. Executes msdb..sp_add_job
3. Executes msdb..sp_add_jobstep (make sure you specify the @proxy_name parameter!)
4. Executes msdb..sp_add_jobserver
5. Executes msdb..sp_add_jobschedule
I may be missing something, but this should put you on the right track. See books online for privileges required to run the stored procedures starting with: msdn.microsoft.com/en-us/library/ms182079.aspx (sp_add_job).