dynamic PropertyGroup / Panel
Using Custom Properties (ID properties) works:

for key, key_type in props.items():
    context.active_object[MinkoScript.format_property_name(i, key)] = script.get_property_default_value(key)


In order to be able to iterate on a specific script properties to draw the panel, I also store the properties dict in an ID property:

context.active_object[MinkoScript.format_property_name(i, '$properties')] = props


Then in the panel:

for i in range(0, context.active_object['minko_num_scripts']):
    layout.label(
        context.active_object[MinkoScript.format_property_name(i, '$name')] + ':',
        icon='TEXT'
    )
    box = layout.box()
    script_id = 'minko_script_' + str(i)
    script_props = context.active_object[MinkoScript.format_property_name(i, '$properties')]
    keys = sorted(script_props.keys())
    for key in keys:
        row = box.row(True)
        col = row.column(True)
        col.label(key + ':')
        col = row.column(True)
        col.prop(
            context.active_object,
            '["' + MinkoScript.format_property_name(i, key) + '"]',
            text=''
        )
    row = box.row(True)
    row.operator(MinkoRemoveScriptOperator.bl_idname, text="Remove").script_id = i
    row.operator(MinkoReloadScriptOperator.bl_idname, text="Reload").script_id = i